diff --git a/.trinity/seals/race_igla-race-ternary-gemm.json b/.trinity/seals/race_igla-race-ternary-gemm.json index eea30f21a5..d87f622463 100644 --- a/.trinity/seals/race_igla-race-ternary-gemm.json +++ b/.trinity/seals/race_igla-race-ternary-gemm.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+cc19d1fcd", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/base/types.t27", @@ -7,23 +7,28 @@ }, { "spec": "specs/igla/race/ternary_mac.t27", - "spec_hash": "sha256:c14549c69c9de5701d69e87b5201937a9e667c5b45999d877656e9e42f67bb3f" + "spec_hash": "sha256:3b6886c1ccdb8194f61f0da6fbb2fc51296af62429d35f5ed62bb59a5d4c6fc4" } ], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:f1b0075cd371feb784f33edd94211b89da59df24e7e8e34de4b8d4ff8b80a6b4", - "gen_hash_rust": "sha256:0b2e87b25c58b0a6335805eca236de07a58e90c8bb467ffccb7c9c2621b2a84e", - "gen_hash_verilog": "sha256:bdb73e5382e4a52ed2f2fec2619aa768e115d4d9e4df373520e8ef0049e38470", - "gen_hash_zig": "sha256:1e4a30536ce65e34edd0da1c20c64d6c68e81433a69efced1e9236bf971cce8d", + "gen_hash_c": "sha256:91c7742b2a806f4c5acd017c24fc67cd9338badf07ad9b4fed12aa61d4f064d3", + "gen_hash_rust": "sha256:bfa14b5e1c5779e194e01750c2a79e9a909cc454f9027c9e481b9cc144a62d7c", + "gen_hash_verilog": "sha256:739a3c1d01dad7de53b171711a22f0795a991765c6f4ab9b87ecdd4c7d2495e7", + "gen_hash_zig": "sha256:930ee5117de461f96363748cccb6cfe15a7dad4f32ed3206e4cd327c96ea8671", "module": "igla-race-ternary-gemm", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-11T10:43:15Z", + "sealed_at": "2026-10-18T10:07:48Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:607d9e99f30688eb84635aa46ad305d3a08ee9fba01b2e0ec7a093276bcad285", + "spec_hash": "sha256:fcfc297bcb7b9f71736b27eaa807cbebdc3055ff598e837816430f883acadb8b", "spec_path": "specs/igla/race/ternary_gemm.t27", "tests": { - "blocked": "does not compile: spec.zig:504:49: error: expected '}', found ':'" + "failed": 0, + "failing": [], + "forced": false, + "passed": 270, + "total": 270, + "vacuous": 144 }, "toolchain": { "test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d", diff --git a/.trinity/seals/race_igla-race-ternary-mac.json b/.trinity/seals/race_igla-race-ternary-mac.json index bbc12037d1..24f1b926e4 100644 --- a/.trinity/seals/race_igla-race-ternary-mac.json +++ b/.trinity/seals/race_igla-race-ternary-mac.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+093bf4713", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/base/types.t27", @@ -7,24 +7,24 @@ } ], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:4b8b37b37919dde566e6263d6c43bbdfc2c046383d2551481d9fd26ca640fca9", - "gen_hash_rust": "sha256:944e4757994dd97494c1e88716b759606e7a3ba80c2fcbb143f01187e39f53d0", - "gen_hash_verilog": "sha256:6924ed39e86148c73bd432717857f449a4a0fc47a82108adbd1bf171c437bf04", - "gen_hash_zig": "sha256:9048245fd5d4fd2a5a20f57950ac8bdeee91c8b2cc22ab3b44b93e0407c1086d", + "gen_hash_c": "sha256:526daf9c7e7f9dfd7ee11474ae2e3edd5a7126e44f523c16e5a675ff7565336e", + "gen_hash_rust": "sha256:3bb86831726d7b22cc93a157f6f0cff83a9c4085b01f08e9de00193dbe32252b", + "gen_hash_verilog": "sha256:32480abb1ff80318d97714499af15dbd9cd0cacec3bba8cb83f39ee6a09d9da0", + "gen_hash_zig": "sha256:a82362f0a1842213b4516ac663b9404ebe2d1339efe942d31513937fdc214823", "module": "igla-race-ternary-mac", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:30:37Z", + "sealed_at": "2026-10-18T10:07:46Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:ebaaddec95ec69774a208a2a03ac0a2093502d6a38b66beda14d3ec756b1d972", + "spec_hash": "sha256:3b6886c1ccdb8194f61f0da6fbb2fc51296af62429d35f5ed62bb59a5d4c6fc4", "spec_path": "specs/igla/race/ternary_mac.t27", "tests": { "failed": 0, "failing": [], "forced": false, - "passed": 335, - "total": 335, - "vacuous": 0 + "passed": 341, + "total": 341, + "vacuous": 146 }, "toolchain": { "test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d", diff --git a/specs/igla/race/ternary_gemm.t27 b/specs/igla/race/ternary_gemm.t27 index b6b4a1e21a..62e2ba2f36 100644 --- a/specs/igla/race/ternary_gemm.t27 +++ b/specs/igla/race/ternary_gemm.t27 @@ -1,7 +1,10 @@ // SPDX-License-Identifier: Apache-2.0 // t27/specs/igla/race/ternary_gemm.t27 -// Ternary GEMM specification -- 2x2 matrix multiply with {-1,0,+1} weights +// Ternary GEMM specification -- 2x2, 4x4 and 8x8 matrix multiply with {-1,0,+1} weights // Uses flattened 1D arrays; zero * operators in multiply path (R-SI-1) +// Exact: activations are i8, the result is i32, and every product is formed in i32 first +// (ternary_mac_wide), so -128 times -1 is +128 and nothing wraps. The reference for the +// numbers is specs/igla/coder/ternary_gemm_gpu.t27 (gHashTag/t27#10362). // phi^2 + 1/phi^2 = 3 | TRINITY module igla-race-ternary-gemm; @@ -12,84 +15,67 @@ use igla::race::ternary_mac; // 1. Types // ============================================================================ -// Flattened 2x2 result stored as [c00, c01, c10, c11] -pub const TernaryGemmResult = struct { - data : []i8, -}; - // ============================================================================ // 2. Core Functions // ============================================================================ -// ternary_gemm_2x2(a, w) -> []i8 +// ternary_gemm_2x2(a, w) -> [4]i32 // Computes C = A * W where A is i8 activations and W is ternary weights. // Arrays are flattened row-major: [a00, a01, a10, a11] and [w00, w01, w10, w11]. // Returns flattened result [c00, c01, c10, c11]. -// Uses ternary_mac (no * operator) -- R-SI-1 compliant. -fn ternary_gemm_2x2(a : []i8, w : []TernaryWeight) -> []i8 { +// Uses ternary_mac_wide (no * operator) -- R-SI-1 compliant. +fn ternary_gemm_2x2(a : []i8, w : []TernaryWeight) -> [4]i32 { // Row 0 of output - let c00 = ternary_mac(a[0], w[0], ternary_mac(a[1], w[2], 0)); - let c01 = ternary_mac(a[0], w[1], ternary_mac(a[1], w[3], 0)); + let c00 = ternary_mac_wide(ternary_mac_wide(0, a[1], w[2]), a[0], w[0]); + let c01 = ternary_mac_wide(ternary_mac_wide(0, a[1], w[3]), a[0], w[1]); // Row 1 of output - let c10 = ternary_mac(a[2], w[0], ternary_mac(a[3], w[2], 0)); - let c11 = ternary_mac(a[2], w[1], ternary_mac(a[3], w[3], 0)); + let c10 = ternary_mac_wide(ternary_mac_wide(0, a[3], w[2]), a[2], w[0]); + let c11 = ternary_mac_wide(ternary_mac_wide(0, a[3], w[3]), a[2], w[1]); return [c00, c01, c10, c11]; } -// ternary_gemm_2x2_as_struct(a, w) -> TernaryGemmResult -// Wrapper returning the struct form for typed consumers. -fn ternary_gemm_2x2_as_struct(a : []i8, w : []TernaryWeight) -> TernaryGemmResult { - let flat = ternary_gemm_2x2(a, w); - return TernaryGemmResult { data: flat }; -} - // ============================================================================ // 3. 4x4 Ternary GEMM // ============================================================================ -// ternary_gemm_4x4(a, w) -> []i8 +// ternary_gemm_4x4(a, w) -> [16]i32 // Computes C = A * W where A and W are 4x4. // Arrays are flattened row-major: a[16], w[16]. // Returns flattened result [c00..c33]. -// Uses ternary_mac (no * operator) -- R-SI-1 compliant. -fn ternary_gemm_4x4(a : []i8, w : []TernaryWeight) -> []i8 { +// Uses ternary_mac_wide (no * operator) -- R-SI-1 compliant. +fn ternary_gemm_4x4(a : []i8, w : []TernaryWeight) -> [16]i32 { // Row 0 - let c00 = ternary_mac(a[0], w[0], ternary_mac(a[1], w[4], ternary_mac(a[2], w[8], ternary_mac(a[3], w[12], 0)))); - let c01 = ternary_mac(a[0], w[1], ternary_mac(a[1], w[5], ternary_mac(a[2], w[9], ternary_mac(a[3], w[13], 0)))); - let c02 = ternary_mac(a[0], w[2], ternary_mac(a[1], w[6], ternary_mac(a[2], w[10], ternary_mac(a[3], w[14], 0)))); - let c03 = ternary_mac(a[0], w[3], ternary_mac(a[1], w[7], ternary_mac(a[2], w[11], ternary_mac(a[3], w[15], 0)))); + let c00 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[3], w[12]), a[2], w[8]), a[1], w[4]), a[0], w[0]); + let c01 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[3], w[13]), a[2], w[9]), a[1], w[5]), a[0], w[1]); + let c02 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[3], w[14]), a[2], w[10]), a[1], w[6]), a[0], w[2]); + let c03 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[3], w[15]), a[2], w[11]), a[1], w[7]), a[0], w[3]); // Row 1 - let c10 = ternary_mac(a[4], w[0], ternary_mac(a[5], w[4], ternary_mac(a[6], w[8], ternary_mac(a[7], w[12], 0)))); - let c11 = ternary_mac(a[4], w[1], ternary_mac(a[5], w[5], ternary_mac(a[6], w[9], ternary_mac(a[7], w[13], 0)))); - let c12 = ternary_mac(a[4], w[2], ternary_mac(a[5], w[6], ternary_mac(a[6], w[10], ternary_mac(a[7], w[14], 0)))); - let c13 = ternary_mac(a[4], w[3], ternary_mac(a[5], w[7], ternary_mac(a[6], w[11], ternary_mac(a[7], w[15], 0)))); + let c10 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[7], w[12]), a[6], w[8]), a[5], w[4]), a[4], w[0]); + let c11 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[7], w[13]), a[6], w[9]), a[5], w[5]), a[4], w[1]); + let c12 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[7], w[14]), a[6], w[10]), a[5], w[6]), a[4], w[2]); + let c13 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[7], w[15]), a[6], w[11]), a[5], w[7]), a[4], w[3]); // Row 2 - let c20 = ternary_mac(a[8], w[0], ternary_mac(a[9], w[4], ternary_mac(a[10], w[8], ternary_mac(a[11], w[12], 0)))); - let c21 = ternary_mac(a[8], w[1], ternary_mac(a[9], w[5], ternary_mac(a[10], w[9], ternary_mac(a[11], w[13], 0)))); - let c22 = ternary_mac(a[8], w[2], ternary_mac(a[9], w[6], ternary_mac(a[10], w[10], ternary_mac(a[11], w[14], 0)))); - let c23 = ternary_mac(a[8], w[3], ternary_mac(a[9], w[7], ternary_mac(a[10], w[11], ternary_mac(a[11], w[15], 0)))); + let c20 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[11], w[12]), a[10], w[8]), a[9], w[4]), a[8], w[0]); + let c21 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[11], w[13]), a[10], w[9]), a[9], w[5]), a[8], w[1]); + let c22 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[11], w[14]), a[10], w[10]), a[9], w[6]), a[8], w[2]); + let c23 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[11], w[15]), a[10], w[11]), a[9], w[7]), a[8], w[3]); // Row 3 - let c30 = ternary_mac(a[12], w[0], ternary_mac(a[13], w[4], ternary_mac(a[14], w[8], ternary_mac(a[15], w[12], 0)))); - let c31 = ternary_mac(a[12], w[1], ternary_mac(a[13], w[5], ternary_mac(a[14], w[9], ternary_mac(a[15], w[13], 0)))); - let c32 = ternary_mac(a[12], w[2], ternary_mac(a[13], w[6], ternary_mac(a[14], w[10], ternary_mac(a[15], w[14], 0)))); - let c33 = ternary_mac(a[12], w[3], ternary_mac(a[13], w[7], ternary_mac(a[14], w[11], ternary_mac(a[15], w[15], 0)))); + let c30 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[15], w[12]), a[14], w[8]), a[13], w[4]), a[12], w[0]); + let c31 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[15], w[13]), a[14], w[9]), a[13], w[5]), a[12], w[1]); + let c32 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[15], w[14]), a[14], w[10]), a[13], w[6]), a[12], w[2]); + let c33 = ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(ternary_mac_wide(0, a[15], w[15]), a[14], w[11]), a[13], w[7]), a[12], w[3]); return [c00, c01, c02, c03, c10, c11, c12, c13, c20, c21, c22, c23, c30, c31, c32, c33]; } -// ternary_gemm_4x4_as_struct(a, w) -> TernaryGemmResult -// Wrapper returning the struct form for typed consumers. -fn ternary_gemm_4x4_as_struct(a : []i8, w : []TernaryWeight) -> TernaryGemmResult { - let flat = ternary_gemm_4x4(a, w); - return TernaryGemmResult { data: flat }; -} - // ============================================================================ // 4. Helpers for verification // ============================================================================ -// get_elem_2x2(flat, row, col) -> i8 +// get_elem_2x2(flat, row, col) -> i32 // Extract element from flattened 2x2 result. -fn get_elem_2x2(flat : []i8, row : u32, col : u32) -> i8 { +fn get_elem_2x2(flat : []i32, row : u32, col : u32) -> i32 { + if (row >= 2) { return 0; } + if (col >= 2) { return 0; } let idx = row * 2 + col; if (idx < flat.len()) { return flat[idx]; @@ -101,21 +87,21 @@ fn get_elem_2x2(flat : []i8, row : u32, col : u32) -> i8 { // 4. Tests // ============================================================================ -test ternary_gemm_identity +test ternary_gemm_checker_weights given a = [5, 3, 7, 2] given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] when out = ternary_gemm_2x2(a, w) - then out[0] == 5 && out[1] == 3 && out[2] == 7 && out[3] == 2 + then out[0] == -2 && out[1] == 2 && out[2] == -5 && out[3] == 5 test ternary_gemm_negative_weights given a = [4, 2, 1, 3] given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }] when out = ternary_gemm_2x2(a, w) - then out[0] == -2 && out[1] == 6 && out[2] == -2 && out[3] == -1 + then out[0] == -2 && out[1] == -4 && out[2] == -3 && out[3] == -1 test ternary_gemm_zero_weights given a = [9, 8, 7, 6] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] + given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_2x2(a, w) then out[0] == 0 && out[1] == 0 && out[2] == 0 && out[3] == 0 @@ -123,19 +109,13 @@ test ternary_gemm_mixed given a = [3, 4, 5, 6] given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] when out = ternary_gemm_2x2(a, w) - then out[0] == 3 && out[1] == -3 && out[2] == 5 && out[3] == -5 + then out[0] == 1 && out[1] == -4 && out[2] == 1 && out[3] == -6 test ternary_gemm_shape given a = [1, 0, 0, 1] given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] when out = ternary_gemm_2x2(a, w) - then len(out) == 4 - -test ternary_gemm_struct_wrap - given a = [1, 2, 3, 4] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] - when res = ternary_gemm_2x2_as_struct(a, w) - then len(res.data) == 4 + then len(out) == 4 && out[0] == -1 && out[1] == 1 && out[2] == 1 && out[3] == -1 test get_elem_2x2_basic given flat = [10, 20, 30, 40] @@ -147,9 +127,11 @@ test get_elem_2x2_oob when e = get_elem_2x2(flat, 2, 0) then e == 0 -// get_elem_4x4(flat, row, col) -> i8 +// get_elem_4x4(flat, row, col) -> i32 // Extract element from flattened 4x4 result. -fn get_elem_4x4(flat : []i8, row : u32, col : u32) -> i8 { +fn get_elem_4x4(flat : []i32, row : u32, col : u32) -> i32 { + if (row >= 4) { return 0; } + if (col >= 4) { return 0; } let idx = row * 4 + col; if (idx < flat.len()) { return flat[idx]; @@ -162,14 +144,14 @@ test get_elem_4x4_basic when e = get_elem_4x4(flat, 2, 1) then e == 10 -test ternary_gemm_4x4_identity +test ternary_gemm_4x4_unit_activations_select_weight_rows given a = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] when out = ternary_gemm_4x4(a, w) - then out[0] == 1 && out[1] == 0 && out[2] == 0 && out[3] == 1 + then out[0] == -1 && out[1] == 1 && out[2] == 1 && out[3] == -1 && out[12] == -1 && out[13] == 1 && out[14] == 1 && out[15] == -1 test ternary_gemm_4x4_shape given a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] @@ -178,7 +160,7 @@ test ternary_gemm_4x4_shape TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] when out = ternary_gemm_4x4(a, w) - then len(out) == 16 + then len(out) == 16 && out[0] == -10 && out[15] == -58 test ternary_gemm_4x4_mixed given a = [3, 1, 2, 0, 1, 4, 0, 2, 2, 0, 3, 1, 0, 2, 1, 4] @@ -187,55 +169,47 @@ test ternary_gemm_4x4_mixed TernaryWeight { code: 0 }, TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] when out = ternary_gemm_4x4(a, w) - then out[0] == 4 && out[1] == 1 && out[2] == 3 && out[3] == 5 + then out[0] == -2 && out[1] == 0 && out[2] == 1 && out[3] == -2 && out[4] == 1 && out[5] == -3 && out[6] == -2 && out[7] == 1 && out[8] == -3 && out[9] == -1 && out[10] == 4 && out[11] == -3 && out[12] == -2 && out[13] == -3 && out[14] == 3 && out[15] == -2 // ============================================================================ // 6. 8x8 Ternary GEMM // ============================================================================ -// ternary_dot_8x8_elem(a, w, a_base, w_col, k, acc) -> i32 -// Recursive dot product for one element of 8x8 result. -fn ternary_dot_8x8_elem(a : []i8, w : []TernaryWeight, a_base : u32, w_col : u32, k : u32, acc : i32) -> i32 { - if (k >= 8) { return acc; } +// ternary_dot_nxn(a, w, n, a_base, w_col, k, acc) -> i32 +// Recursive exact dot product for one element of an n x n result: row starting at a_base of +// A against column w_col of W, from k up to n. Every product is formed in i32. +fn ternary_dot_nxn(a : []i8, w : []TernaryWeight, n : u32, a_base : u32, w_col : u32, k : u32, acc : i32) -> i32 { + if (k >= n) { return acc; } let a_idx = a_base + k; - let w_idx = k * 8 + w_col; - let prod = ternary_mul(a[a_idx], w[w_idx]); - return ternary_dot_8x8_elem(a, w, a_base, w_col, k + 1, acc + prod); + let w_idx = k * n + w_col; + let prod = ternary_mul_wide(a[a_idx], w[w_idx]); + return ternary_dot_nxn(a, w, n, a_base, w_col, k + 1, acc + prod); } -// ternary_gemm_8x8_cols(a, w, row, col) -> []i8 -// Recursively compute one row of 8x8 result. -fn ternary_gemm_8x8_cols(a : []i8, w : []TernaryWeight, row : u32, col : u32) -> []i8 { - if (col >= 8) { return []i8{}; } - let a_base = row * 8; - let elem = ternary_dot_8x8_elem(a, w, a_base, col, 0, 0) as i8; - return [elem] + ternary_gemm_8x8_cols(a, w, row, col + 1); +// ternary_dot_8x8_elem(a, w, a_base, w_col, k, acc) -> i32 +// Recursive dot product for one element of 8x8 result. +fn ternary_dot_8x8_elem(a : []i8, w : []TernaryWeight, a_base : u32, w_col : u32, k : u32, acc : i32) -> i32 { + return ternary_dot_nxn(a, w, 8, a_base, w_col, k, acc); } -// ternary_gemm_8x8_rows(a, w, row) -> []i8 -// Recursively compute all rows of 8x8 result. -fn ternary_gemm_8x8_rows(a : []i8, w : []TernaryWeight, row : u32) -> []i8 { - if (row >= 8) { return []i8{}; } - let row_vec = ternary_gemm_8x8_cols(a, w, row, 0); - return row_vec + ternary_gemm_8x8_rows(a, w, row + 1); +// ternary_gemm_8x8_elem(a, w, row, col) -> i32 +// Element (row, col) of the 8x8 result. +fn ternary_gemm_8x8_elem(a : []i8, w : []TernaryWeight, row : u32, col : u32) -> i32 { + return ternary_dot_nxn(a, w, 8, row * 8, col, 0, 0); } -// ternary_gemm_8x8(a, w) -> []i8 +// ternary_gemm_8x8(a, w) -> [64]i32 // Computes C = A * W where A and W are 8x8. // Arrays are flattened row-major: a[64], w[64]. // Returns flattened result [c00..c77]. -fn ternary_gemm_8x8(a : []i8, w : []TernaryWeight) -> []i8 { - return ternary_gemm_8x8_rows(a, w, 0); -} - -// ternary_gemm_8x8_as_struct(a, w) -> TernaryGemmResult -fn ternary_gemm_8x8_as_struct(a : []i8, w : []TernaryWeight) -> TernaryGemmResult { - let flat = ternary_gemm_8x8(a, w); - return TernaryGemmResult { data: flat }; +fn ternary_gemm_8x8(a : []i8, w : []TernaryWeight) -> [64]i32 { + return [ternary_gemm_8x8_elem(a, w, 0, 0), ternary_gemm_8x8_elem(a, w, 0, 1), ternary_gemm_8x8_elem(a, w, 0, 2), ternary_gemm_8x8_elem(a, w, 0, 3), ternary_gemm_8x8_elem(a, w, 0, 4), ternary_gemm_8x8_elem(a, w, 0, 5), ternary_gemm_8x8_elem(a, w, 0, 6), ternary_gemm_8x8_elem(a, w, 0, 7), ternary_gemm_8x8_elem(a, w, 1, 0), ternary_gemm_8x8_elem(a, w, 1, 1), ternary_gemm_8x8_elem(a, w, 1, 2), ternary_gemm_8x8_elem(a, w, 1, 3), ternary_gemm_8x8_elem(a, w, 1, 4), ternary_gemm_8x8_elem(a, w, 1, 5), ternary_gemm_8x8_elem(a, w, 1, 6), ternary_gemm_8x8_elem(a, w, 1, 7), ternary_gemm_8x8_elem(a, w, 2, 0), ternary_gemm_8x8_elem(a, w, 2, 1), ternary_gemm_8x8_elem(a, w, 2, 2), ternary_gemm_8x8_elem(a, w, 2, 3), ternary_gemm_8x8_elem(a, w, 2, 4), ternary_gemm_8x8_elem(a, w, 2, 5), ternary_gemm_8x8_elem(a, w, 2, 6), ternary_gemm_8x8_elem(a, w, 2, 7), ternary_gemm_8x8_elem(a, w, 3, 0), ternary_gemm_8x8_elem(a, w, 3, 1), ternary_gemm_8x8_elem(a, w, 3, 2), ternary_gemm_8x8_elem(a, w, 3, 3), ternary_gemm_8x8_elem(a, w, 3, 4), ternary_gemm_8x8_elem(a, w, 3, 5), ternary_gemm_8x8_elem(a, w, 3, 6), ternary_gemm_8x8_elem(a, w, 3, 7), ternary_gemm_8x8_elem(a, w, 4, 0), ternary_gemm_8x8_elem(a, w, 4, 1), ternary_gemm_8x8_elem(a, w, 4, 2), ternary_gemm_8x8_elem(a, w, 4, 3), ternary_gemm_8x8_elem(a, w, 4, 4), ternary_gemm_8x8_elem(a, w, 4, 5), ternary_gemm_8x8_elem(a, w, 4, 6), ternary_gemm_8x8_elem(a, w, 4, 7), ternary_gemm_8x8_elem(a, w, 5, 0), ternary_gemm_8x8_elem(a, w, 5, 1), ternary_gemm_8x8_elem(a, w, 5, 2), ternary_gemm_8x8_elem(a, w, 5, 3), ternary_gemm_8x8_elem(a, w, 5, 4), ternary_gemm_8x8_elem(a, w, 5, 5), ternary_gemm_8x8_elem(a, w, 5, 6), ternary_gemm_8x8_elem(a, w, 5, 7), ternary_gemm_8x8_elem(a, w, 6, 0), ternary_gemm_8x8_elem(a, w, 6, 1), ternary_gemm_8x8_elem(a, w, 6, 2), ternary_gemm_8x8_elem(a, w, 6, 3), ternary_gemm_8x8_elem(a, w, 6, 4), ternary_gemm_8x8_elem(a, w, 6, 5), ternary_gemm_8x8_elem(a, w, 6, 6), ternary_gemm_8x8_elem(a, w, 6, 7), ternary_gemm_8x8_elem(a, w, 7, 0), ternary_gemm_8x8_elem(a, w, 7, 1), ternary_gemm_8x8_elem(a, w, 7, 2), ternary_gemm_8x8_elem(a, w, 7, 3), ternary_gemm_8x8_elem(a, w, 7, 4), ternary_gemm_8x8_elem(a, w, 7, 5), ternary_gemm_8x8_elem(a, w, 7, 6), ternary_gemm_8x8_elem(a, w, 7, 7)]; } -// get_elem_8x8(flat, row, col) -> i8 -fn get_elem_8x8(flat : []i8, row : u32, col : u32) -> i8 { +// get_elem_8x8(flat, row, col) -> i32 +fn get_elem_8x8(flat : []i32, row : u32, col : u32) -> i32 { + if (row >= 8) { return 0; } + if (col >= 8) { return 0; } let idx = row * 8 + col; if (idx < flat.len()) { return flat[idx]; @@ -256,7 +230,7 @@ test ternary_gemm_8x8_shape given a = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_8x8(a, w) - then len(out) == 64 + then len(out) == 64 && out[0] == 0 && out[63] == 0 test ternary_gemm_8x8_ones given a = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] @@ -332,16 +306,10 @@ test ternary_gemm_2x2_large_activations_2 given a = [127, -128, 64, -64] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) - then out[0] == 63 && out[1] == -64 && out[2] == 0 && out[3] == -128 - -test get_elem_2x2_negative_indices_2 - given flat = [10, 20, 30, 40] - when e = get_elem_2x2(flat, 0, -1) - then e == 0 - + then out[0] == 127 && out[1] == -255 && out[2] == 64 && out[3] == -128 test get_elem_8x8_oob_2 - given flat = [0; 64] + given flat = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] when e = get_elem_8x8(flat, 8, 0) then e == 0 @@ -352,7 +320,7 @@ test ternary_gemm_4x4_mixed_weights TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }] when out = ternary_gemm_4x4(a, w) - then len(out) == 16 + then len(out) == 16 && out[0] == 4 && out[1] == -4 && out[2] == 0 && out[3] == 4 && out[12] == 22 && out[13] == -22 && out[14] == 0 && out[15] == 22 test get_elem_4x4_diagonal given flat = [10, 0, 0, 0, 0, 20, 0, 0, 0, 0, 30, 0, 0, 0, 0, 40] @@ -362,34 +330,16 @@ test get_elem_4x4_diagonal when e4 = get_elem_4x4(flat, 3, 3) then e == 10 && e2 == 20 && e3 == 30 && e4 == 40 -test ternary_gemm_2x2_negative_weight - given a = [5, -3] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 1 }] - when out = ternary_gemm_2x2(a, w) - then out[0] == -5 && out[1] == -3 - test get_elem_2x2_normal_access given flat = [1, 2, 3, 4] when e = get_elem_2x2(flat, 1, 1) then e == 4 -test ternary_gemm_2x2_mismatched_short_arrays - given a = [1, 2] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] - when out = ternary_gemm_2x2(a, w) - then out[0] == 3 && out[1] == 3 && out[2] == 0 && out[3] == 0 - -test ternary_gemm_2x2_i32_to_i8_implicit_truncation +test ternary_gemm_2x2_min_activations_do_not_wrap given a = [-128, -128, -128, -128] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) - then out[0] == 0 && out[1] == 0 && out[2] == 0 && out[3] == 0 - -test ternary_gemm_2x2_empty_arrays_oob - given a = []i8{} - given w = []TernaryWeight{} - when out = ternary_gemm_2x2(a, w) - then out[0] == 0 && out[3] == 0 + then out[0] == -256 && out[1] == -256 && out[2] == -256 && out[3] == -256 test ternary_gemm_4x4_all_minus_one_max_activations given a = [127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127] @@ -398,7 +348,7 @@ test ternary_gemm_4x4_all_minus_one_max_activations TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] when out = ternary_gemm_4x4(a, w) - then out[0] == 4 && out[15] == 4 + then out[0] == -508 && out[15] == -508 // ============================================================================ // 5. Invariants @@ -443,11 +393,12 @@ invariant get_elem_2x2_bounds row >= 2 || col >= 2 ==> get_elem_2x2(flat, row, col) == 0 -bench ternary_gemm_2x2_latency - given a = [1, -1, 0, 1] - given w = [TernaryWeight { w: -1 }, TernaryWeight { w: 0 }, TernaryWeight { w: 1 }, TernaryWeight { w: -1 }] - measure ternary_gemm_2x2(a, w) - target latency_ms < 1.0 +bench "ternary_gemm_2x2_latency" { + // Target: ternary_gemm_2x2, latency_ms < 1.0 + const a = [1, -1, 0, 1]; + const w = [TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }]; + _ = ternary_gemm_2x2(a, w); +} test get_elem_8x8_last_valid given flat = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64] @@ -460,23 +411,11 @@ test ternary_gemm_8x8_sparse_peak when out = ternary_gemm_8x8(a, w) then out[0] == 127 && out[63] == 0 -test ternary_gemm_4x4_as_struct_wrap - given a = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when res = ternary_gemm_4x4_as_struct(a, w) - then len(res.data) == 16 - test get_elem_8x8_oob_exact_corner - given flat = [0; 64] + given flat = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] when e = get_elem_8x8(flat, 8, 8) then e == 0 -test ternary_gemm_8x8_empty_input - given a = [] - given w = [] - when out = ternary_gemm_8x8(a, w) - then len(out) == 0 - test ternary_gemm_4x4_invalid_weight_code given a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] given w = [TernaryWeight { code: 255 }, TernaryWeight { code: 255 }, TernaryWeight { code: 255 }, TernaryWeight { code: 255 }, @@ -487,31 +426,18 @@ test ternary_gemm_4x4_invalid_weight_code then out[0] == 0 && out[15] == 0 test get_elem_8x8_negative_row_col - given flat = [0; 64] + given flat = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] when e = get_elem_8x8(flat, 255, 255) then e == 0 - test ternary_dot_8x8_elem_k_exceeds_8_returns_acc given a = [1, 2, 3, 4, 5, 6, 7, 8] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when r = ternary_dot_8x8_elem(a, w, 0, 0, 8, 42) then r == 42 -test ternary_gemm_8x8_cols_col_exceeds_returns_empty - given a = [1, 2, 3, 4, 5, 6, 7, 8] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] - when cols = ternary_gemm_8x8_cols(a, w, 0, 8) - then len(cols) == 0 - -test ternary_gemm_2x2_short_weights_oob_zero - given a = [5, 6, 7, 8] - given w = [TernaryWeight { code: 1 }] - when out = ternary_gemm_2x2(a, w) - then out[0] == 5 && out[1] == 0 && out[2] == 7 && out[3] == 0 - test get_elem_8x8_empty_flat_returns_zero - given flat = []i8{} + given flat = []i32{} when e = get_elem_8x8(flat, 0, 0) then e == 0 @@ -522,7 +448,7 @@ test get_elem_4x4_last_element test ternary_gemm_4x4_all_zero_weights given a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] - given w = [TernaryWeight { code: 0 }; 16] + given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_4x4(a, w) then out[0] == 0 && out[5] == 0 && out[10] == 0 && out[15] == 0 @@ -535,7 +461,7 @@ test ternary_gemm_2x2_negative_activations given a = [-1, -2, -3, -4] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) - then out[0] == -3 && out[1] == -7 && out[2] == -7 && out[3] == -11 + then out[0] == -3 && out[1] == -3 && out[2] == -7 && out[3] == -7 test ternary_gemm_2x2_zero_weights given a = [1, 2, 3, 4] @@ -572,8 +498,8 @@ test get_elem_2x2_out_of_bounds then e == 0 test ternary_gemm_4x4_zero_input_2 - given a = [0; 16] - given w = [TernaryWeight { code: 1 }; 16] + given a = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_4x4(a, w) then out[0] == 0 && out[5] == 0 && out[10] == 0 && out[15] == 0 @@ -604,10 +530,11 @@ test get_elem_8x8_middle_element when e = get_elem_8x8(flat, 3, 3) then e == 28 -bench phi_computation_latency - given phi_val = 1.618 - measure phi_val * phi_val + 1.0 / (phi_val * phi_val) - target latency_us < 1.0 +bench "phi_computation_latency" { + // Target: latency_us < 1.0 + const phi_val = 1.618; + _ = phi_val * phi_val + 1.0 / (phi_val * phi_val); +} test ternary_gemm_2x2_zero_weights_all_zero given a = [1, 2, 3, 4] @@ -621,28 +548,19 @@ test get_elem_8x8_origin then e == 1 test ternary_gemm_8x8_sparse_identity_peak - given a = [1, 0, 0, 0, 0, 0, 0, 0] + [0; 56] - given w = [TernaryWeight { code: 1 }] + [TernaryWeight { code: 0 }; 63] + given a = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_8x8(a, w) then out[0] == 1 && out[1] == 0 && out[63] == 0 -test ternary_gemm_4x4_as_struct_exact_values - given a = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, - TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, - TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, - TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when res = ternary_gemm_4x4_as_struct(a, w) - then res.data[0] == 1 && res.data[5] == 1 && res.data[10] == 1 && res.data[15] == 1 - test get_elem_2x2_bottom_left given flat = [1, 2, 3, 4] when e = get_elem_2x2(flat, 1, 0) then e == 3 test ternary_gemm_4x4_zero_lhs_all_zero - given a = [0; 16] - given w = [TernaryWeight { code: 1 }; 16] + given a = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_4x4(a, w) then out[0] == 0 && out[15] == 0 @@ -657,12 +575,6 @@ test ternary_gemm_2x2_all_minus_weights_sum_neg when out = ternary_gemm_2x2(a, w) then out[0] == -2 && out[1] == -2 && out[2] == -2 && out[3] == -2 -test ternary_gemm_8x8_as_struct_identity - given a = [1] + [0; 63] - given w = [TernaryWeight { code: 1 }] + [TernaryWeight { code: 0 }; 63] - when res = ternary_gemm_8x8_as_struct(a, w) - then len(res.data) == 64 && res.data[0] == 1 - test get_elem_8x8_diagonal given flat = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64] when e0 = get_elem_8x8(flat, 0, 0) @@ -680,22 +592,21 @@ test ternary_gemm_4x4_identity_matrix then out[0] == 1 && out[5] == 1 && out[10] == 1 && out[15] == 1 test get_elem_8x8_oob_row - given flat = [0; 64] + given flat = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] when e = get_elem_8x8(flat, 8, 0) then e == 0 -test ternary_gemm_2x2_transpose_like +test ternary_gemm_2x2_identity_weights_preserve_activations given a = [0, 1, 2, 3] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) - then out[0] == 3 && out[3] == 3 + then out[0] == 0 && out[1] == 1 && out[2] == 2 && out[3] == 3 test get_elem_4x4_oob_col given flat = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] when e = get_elem_4x4(flat, 0, 4) then e == 0 - test ternary_gemm_2x2_zero_weights_2 given a = [5, 6, 7, 8] given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] @@ -717,7 +628,7 @@ test ternary_gemm_2x2_mixed_weights given a = [1, 2, 3, 4] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) - then out[0] == 1 && out[1] == 2 && out[2] == 0 && out[3] == 4 + then out[0] == 1 && out[1] == 1 && out[2] == 3 && out[3] == 1 test get_elem_2x2_out_of_bounds_2 given flat = [1, 2, 3, 4] @@ -744,7 +655,7 @@ test ternary_gemm_2x2_mixed_sign_weights given a = [2, 3, 4, 5] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) - then out[0] == 2 && out[1] == 3 && out[2] == 0 && out[3] == 5 + then out[0] == 2 && out[1] == 1 && out[2] == 4 && out[3] == 1 test ternary_gemm_2x2_all_zero_activations given a = [0, 0, 0, 0] @@ -823,13 +734,13 @@ invariant ternary_gemm_2x2_identity_weights_inv: out[0] == a[0] && out[1] == a[1] && out[2] == a[2] && out[3] == a[3] test ternary_gemm_8x8_identity_first_elem - given a = [cast_i8(1), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0)] + given a = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_8x8(a, w) then out[0] == a[0] test get_elem_8x8_oob_returns_zero - given flat = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8), cast_i8(9), cast_i8(10), cast_i8(11), cast_i8(12), cast_i8(13), cast_i8(14), cast_i8(15), cast_i8(16), cast_i8(17), cast_i8(18), cast_i8(19), cast_i8(20), cast_i8(21), cast_i8(22), cast_i8(23), cast_i8(24), cast_i8(25), cast_i8(26), cast_i8(27), cast_i8(28), cast_i8(29), cast_i8(30), cast_i8(31), cast_i8(32), cast_i8(33), cast_i8(34), cast_i8(35), cast_i8(36), cast_i8(37), cast_i8(38), cast_i8(39), cast_i8(40), cast_i8(41), cast_i8(42), cast_i8(43), cast_i8(44), cast_i8(45), cast_i8(46), cast_i8(47), cast_i8(48), cast_i8(49), cast_i8(50), cast_i8(51), cast_i8(52), cast_i8(53), cast_i8(54), cast_i8(55), cast_i8(56), cast_i8(57), cast_i8(58), cast_i8(59), cast_i8(60), cast_i8(61), cast_i8(62), cast_i8(63), cast_i8(64)] + given flat = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64] when val = get_elem_8x8(flat, 8, 0) then val == 0 @@ -844,13 +755,13 @@ invariant ternary_gemm_4x4_output_len_sixteen len(ternary_gemm_4x4(a, w)) == 16 test ternary_gemm_2x2_zero_input_zero - given a = [cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0)] + given a = [0, 0, 0, 0] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) then out[0] == 0 && out[1] == 0 && out[2] == 0 && out[3] == 0 test ternary_gemm_4x4_identity_first_elem - given a = [cast_i8(1), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0)] + given a = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_4x4(a, w) then out[0] == 1 @@ -858,17 +769,17 @@ test ternary_gemm_4x4_identity_first_elem invariant ternary_gemm_2x2_zero_input_zero_inv forall w : []TernaryWeight len(w) == 4 ==> - let out = ternary_gemm_2x2([cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0)], w) + let out = ternary_gemm_2x2([0, 0, 0, 0], w) out[0] == 0 && out[1] == 0 && out[2] == 0 && out[3] == 0 test ternary_gemm_2x2_all_ones_weights - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] + given a = [1, 2, 3, 4] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) then out[0] == 3 && out[1] == 3 && out[2] == 7 && out[3] == 7 test get_elem_4x4_second_row_first_col - given flat = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8), cast_i8(9), cast_i8(10), cast_i8(11), cast_i8(12), cast_i8(13), cast_i8(14), cast_i8(15), cast_i8(16)] + given flat = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] when val = get_elem_4x4(flat, 1, 0) then val == 5 @@ -880,24 +791,24 @@ invariant ternary_gemm_2x2_all_ones_weights_sum out[0] == a[0] + a[1] && out[1] == a[0] + a[1] && out[2] == a[2] + a[3] && out[3] == a[2] + a[3] test ternary_gemm_2x2_all_minus_one_weights - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] + given a = [1, 2, 3, 4] given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] when out = ternary_gemm_2x2(a, w) then out[0] == -3 && out[1] == -3 && out[2] == -7 && out[3] == -7 test get_elem_4x4_oob_col_returns_zero - given flat = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8), cast_i8(9), cast_i8(10), cast_i8(11), cast_i8(12), cast_i8(13), cast_i8(14), cast_i8(15), cast_i8(16)] + given flat = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] when val = get_elem_4x4(flat, 0, 4) then val == 0 test ternary_gemm_2x2_invalid_weight_code - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] + given a = [1, 2, 3, 4] given w = [TernaryWeight { code: 3 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] when out = ternary_gemm_2x2(a, w) - then out[0] == 0 && out[1] == 1 && out[2] == 0 && out[3] == -4 + then out[0] == 2 && out[1] == -2 && out[2] == 4 && out[3] == -4 test ternary_gemm_4x4_invalid_weight_code_identity - given a = [cast_i8(1), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(1), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(1), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(1)] + given a = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] given w = [TernaryWeight { code: 3 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 3 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 3 }, TernaryWeight { code: 0 }, @@ -919,13 +830,13 @@ invariant ternary_gemm_2x2_all_minus_one_weights_sum out[0] == -(a[0] + a[1]) && out[1] == -(a[0] + a[1]) && out[2] == -(a[2] + a[3]) && out[3] == -(a[2] + a[3]) test ternary_gemm_2x2_zero_activations_all_zero - given a = [cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0)] + given a = [0, 0, 0, 0] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) then out[0] == 0 && out[1] == 0 && out[2] == 0 && out[3] == 0 test ternary_gemm_2x2_identity_weights_positive_activations - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] + given a = [1, 2, 3, 4] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) then out[0] == 3 && out[1] == 3 && out[2] == 7 && out[3] == 7 @@ -933,17 +844,17 @@ test ternary_gemm_2x2_identity_weights_positive_activations invariant ternary_gemm_2x2_zero_activations_all_zero_inv: forall w : []TernaryWeight len(w) == 4 ==> - let a = [cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0)] + let a = [0, 0, 0, 0] ternary_gemm_2x2(a, w)[0] == 0 test ternary_gemm_2x2_all_plus_one_weights - given a = [cast_i8(1), cast_i8(1), cast_i8(1), cast_i8(1)] + given a = [1, 1, 1, 1] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) then out[0] == 2 && out[1] == 2 && out[2] == 2 && out[3] == 2 test ternary_gemm_2x2_all_minus_one_activations - given a = [cast_i8(-1), cast_i8(-1), cast_i8(-1), cast_i8(-1)] + given a = [-1, -1, -1, -1] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) then out[0] == -2 && out[1] == -2 && out[2] == -2 && out[3] == -2 @@ -956,13 +867,13 @@ invariant ternary_gemm_2x2_all_plus_one_weights_sum_inv: out[0] == a[0] + a[1] && out[1] == a[0] + a[1] && out[2] == a[2] + a[3] && out[3] == a[2] + a[3] test ternary_gemm_2x2_all_minus_one_activations_plus_weights - given a = [cast_i8(-1), cast_i8(-1), cast_i8(-1), cast_i8(-1)] + given a = [-1, -1, -1, -1] given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] when out = ternary_gemm_2x2(a, w) then out[0] == 2 && out[1] == 2 && out[2] == 2 && out[3] == 2 test get_elem_2x2_oob_large_row - given flat = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] + given flat = [1, 2, 3, 4] when e = get_elem_2x2(flat, 255, 0) then e == 0 @@ -972,12 +883,12 @@ invariant get_elem_2x2_oob_large_row_inv: get_elem_2x2(flat, 255, 0) == 0 test ternary_gemm_get_elem_2x2_oob_large_col - given flat = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] + given flat = [1, 2, 3, 4] when e = get_elem_2x2(flat, 0, 255) then e == 0 test ternary_gemm_2x2_zero_weights_all_zero_2 - given a = [cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8)] + given a = [5, 6, 7, 8] given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_2x2(a, w) then out[0] == 0 && out[1] == 0 && out[2] == 0 && out[3] == 0 @@ -987,14 +898,8 @@ invariant get_elem_2x2_oob_large_col_inv: len(flat) == 4 ==> get_elem_2x2(flat, 0, 255) == 0 -test ternary_gemm_8x8_as_struct_empty_input - given a = []i8{} - given w = []TernaryWeight{} - when res = ternary_gemm_8x8_as_struct(a, w) - then len(res.data) == 0 - test get_elem_8x8_oob_large_row - given flat = [0; 64] + given flat = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] when e = get_elem_8x8(flat, 255, 0) then e == 0 @@ -1004,13 +909,13 @@ invariant get_elem_8x8_oob_large_row_inv: get_elem_8x8(flat, 255, 0) == 0 test ternary_gemm_2x2_single_plus_weight - given a = [cast_i8(3), cast_i8(0), cast_i8(0), cast_i8(0)] + given a = [3, 0, 0, 0] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_2x2(a, w) then out[0] == 3 test ternary_gemm_2x2_single_minus_weight - given a = [cast_i8(5), cast_i8(0), cast_i8(0), cast_i8(0)] + given a = [5, 0, 0, 0] given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_2x2(a, w) then out[0] == -5 @@ -1020,41 +925,36 @@ invariant ternary_gemm_2x2_single_plus_weight_inv: ternary_gemm_2x2([a, 0, 0, 0], [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }])[0] == cast_i16(a) test ternary_gemm_2x2_single_element_minus_weight_row0col1 - given a = [cast_i8(0), cast_i8(4), cast_i8(0), cast_i8(0)] + given a = [4, 0, 0, 0] given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_2x2(a, w) - then out[0] == -4 - -test ternary_gemm_8x8_as_struct_empty_weights - given a = []i8{} - given w = []TernaryWeight{} - when res = ternary_gemm_8x8_as_struct(a, w) - then len(res.data) == 0 + then out[1] == -4 invariant ternary_gemm_2x2_single_element_minus_weight_row0col1_inv: - ternary_gemm_2x2([0, 4, 0, 0], [TernaryWeight { code: 0 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }])[0] == -4 + ternary_gemm_2x2([4, 0, 0, 0], [TernaryWeight { code: 0 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }])[1] == -4 test ternary_gemm_2x2_first_element_broadcast - given a = [cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8)] + given a = [5, 6, 7, 8] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_2x2(a, w) then out[0] == 5 && out[1] == 5 && out[2] == 7 && out[3] == 7 test ternary_gemm_4x4_identity_weights_non_identity_activations - given a = [cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8), cast_i8(9), cast_i8(10), cast_i8(11), cast_i8(12), cast_i8(13), cast_i8(14), cast_i8(15), cast_i8(16), cast_i8(17), cast_i8(18), cast_i8(19), cast_i8(20)] + given a = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when out = ternary_gemm_4x4(a, w) then out[0] == 5 && out[5] == 10 && out[10] == 15 && out[15] == 20 test ternary_gemm_2x2_first_element_broadcast_concrete - given a = [cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8)] + given a = [5, 6, 7, 8] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_2x2(a, w) then out[0] == 5 && out[1] == 5 && out[2] == 7 && out[3] == 7 test ternary_gemm_4x4_identity_2 - given a = [cast_i8(1), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(1), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(1), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(1)] - when out = ternary_gemm_4x4(a, a) + given a = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] + when out = ternary_gemm_4x4(a, w) then out[0] == 1 && out[5] == 1 && out[10] == 1 && out[15] == 1 invariant ternary_gemm_4x4_identity_inv: @@ -1065,7 +965,7 @@ invariant ternary_gemm_4x4_identity_inv: out[0] == a[0] && out[5] == a[5] && out[10] == a[10] && out[15] == a[15] test ternary_gemm_2x2_zero_activations_zero_output - given a = [cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0)] + given a = [0, 0, 0, 0] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] when out = ternary_gemm_2x2(a, w) then out[0] == 0 && out[1] == 0 && out[2] == 0 && out[3] == 0 @@ -1073,12 +973,12 @@ test ternary_gemm_2x2_zero_activations_zero_output invariant ternary_gemm_2x2_zero_activations_zero_output_inv: forall w : []TernaryWeight len(w) == 4 ==> - let a = [cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0)] + let a = [0, 0, 0, 0] let out = ternary_gemm_2x2(a, w) out[0] == 0 && out[1] == 0 && out[2] == 0 && out[3] == 0 test ternary_gemm_2x2_single_plus_weight_broadcast - given a = [cast_i8(3), cast_i8(0), cast_i8(0), cast_i8(0)] + given a = [3, 0, 0, 0] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) then out[0] == 3 && out[1] == 3 && out[2] == 0 && out[3] == 0 @@ -1086,11 +986,11 @@ test ternary_gemm_2x2_single_plus_weight_broadcast invariant ternary_gemm_2x2_single_plus_weight_broadcast_inv: forall a : i8 let w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] - let out = ternary_gemm_2x2([a, cast_i8(0), cast_i8(0), cast_i8(0)], w) + let out = ternary_gemm_2x2([a, 0, 0, 0], w) out[0] == a && out[1] == a test get_elem_8x8_oob_col - given flat = [0; 64] + given flat = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] when e = get_elem_8x8(flat, 0, 8) then e == 0 @@ -1099,7 +999,7 @@ invariant get_elem_8x8_oob_col_inv len(flat) == 64 ==> get_elem_8x8(flat, 0, 8) == 0 test ternary_gemm_identity_weights_trace - given a = [cast_i8(1), cast_i8(0), cast_i8(0), cast_i8(1)] + given a = [1, 0, 0, 1] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) then out[0] == 1 && out[3] == 1 @@ -1107,16 +1007,16 @@ test ternary_gemm_identity_weights_trace invariant ternary_gemm_identity_weights_trace_inv: forall a : i8 let w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - ternary_gemm_2x2([a, cast_i8(0), cast_i8(0), a], w)[0] == a + ternary_gemm_2x2([a, 0, 0, a], w)[0] == a test ternary_gemm_zero_weights_zero_output - given a = [cast_i8(5), cast_i8(3), cast_i8(7), cast_i8(2)] + given a = [5, 3, 7, 2] given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when out = ternary_gemm_2x2(a, w) then out[0] == 0 && out[1] == 0 && out[2] == 0 && out[3] == 0 test ternary_gemm_all_plus_weights_sum - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] + given a = [1, 2, 3, 4] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] when out = ternary_gemm_2x2(a, w) then out[0] == 3 && out[1] == 3 && out[2] == 7 && out[3] == 7 @@ -1124,513 +1024,61 @@ test ternary_gemm_all_plus_weights_sum invariant ternary_gemm_zero_weights_zero_output_inv: forall a : i8 let w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] - ternary_gemm_2x2([a, cast_i8(0), cast_i8(0), a], w)[0] == 0 - -test ternary_gemm_identity_weights_identity_w294 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == 2 - -test ternary_gemm_zero_weights_zero_w294 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 0 && out[1] == 0 - -invariant ternary_gemm_identity_weights_identity_w294_inv: - forall a : []i8 - a.len() == 4 ==> - ternary_gemm(a, [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }]).len() == 4 - -test ternary_gemm_minus_weights_negate_w295 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -1 && out[1] == -2 - -test ternary_gemm_mixed_weights_select_w295 - given a = [cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 - -invariant ternary_gemm_minus_weights_negate_w295_inv: - forall a : []i8 - a.len() == 4 ==> - ternary_gemm(a, [TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 2 }]).len() == 4 - -test ternary_gemm_all_plus_weights_sum_w296 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 3 && out[1] == 3 - -test ternary_gemm_all_minus_weights_neg_sum_w296 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -3 && out[1] == -3 - -invariant ternary_gemm_all_plus_weights_sum_w296_inv: - forall a : []i8 - a.len() == 4 ==> - ternary_gemm(a, [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }]).len() == 4 - -test ternary_gemm_all_zero_weights_zero_w297 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 0 && out[1] == 0 - -test ternary_gemm_identity_preserves_first_element_w297 - given a = [cast_i8(5), cast_i8(0), cast_i8(0), cast_i8(0)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 5 - -invariant ternary_gemm_all_zero_weights_zero_w297_inv: - forall a : []i8 - a.len() == 4 ==> - ternary_gemm(a, [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }]).len() == 4 - -test ternary_gemm_mixed_weights_select_w298 - given a = [cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 11 && out[1] == 1 - -test ternary_gemm_alternating_weights_alternating_w298 - given a = [cast_i8(2), cast_i8(2), cast_i8(2), cast_i8(2)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 0 && out[1] == 0 - -invariant ternary_gemm_alternating_weights_alternating_w298_inv: - forall a : []i8 - a.len() == 4 ==> - ternary_gemm(a, [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }]).len() == 4 - -test ternary_gemm_all_zero_weights_all_zero_w299 - given a = [cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8)] - given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 0 && out[1] == 0 - -test ternary_gemm_uniform_activations_all_plus_w299 - given a = [cast_i8(2), cast_i8(2), cast_i8(2), cast_i8(2)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 4 && out[1] == 4 - -invariant ternary_gemm_all_zero_weights_all_zero_w299_inv: - forall a : []i8 - a.len() == 4 ==> - ternary_gemm(a, [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }]).len() == 4 - -test ternary_gemm_all_minus_weights_negate_all_w300 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -3 && out[1] == -3 - -test ternary_gemm_identity_weights_passthrough_w300 - given a = [cast_i8(5), cast_i8(6), cast_i8(7), cast_i8(8)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 5 && out[1] == 6 - -invariant ternary_gemm_identity_weights_passthrough_w300_inv: - forall a : []i8 - a.len() == 4 ==> - ternary_gemm(a, [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }]).len() == 4 - -test ternary_gemm_mixed_weights_concrete_sum_w301 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == 3 - -test ternary_gemm_all_plus_weights_double_sum_w301 - given a = [cast_i8(3), cast_i8(4), cast_i8(5), cast_i8(6)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 7 && out[1] == 7 - -invariant ternary_gemm_mixed_weights_concrete_sum_w301_inv: - ternary_gemm([cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)], [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }]).len() == 4 - -test ternary_gemm_uniform_activations_identity_weights_passthrough_w302 - given a = [cast_i8(5), cast_i8(5), cast_i8(5), cast_i8(5)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 5 && out[1] == 5 - -test ternary_gemm_all_zero_activations_all_plus_weights_zero_w302 - given a = [cast_i8(0), cast_i8(0), cast_i8(0), cast_i8(0)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 0 && out[1] == 0 - -invariant ternary_gemm_all_zero_activations_all_plus_weights_zero_w302_inv: - forall a : []i8 - a.len() == 4 ==> ternary_gemm(a, [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }]).len() == 4 - -test ternary_gemm_identity_weights_single_element_w303 - given a = [cast_i8(7)] - given w = [TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 1 && out[0] == 7 - -test ternary_gemm_minus_weight_single_element_negate_w303 - given a = [cast_i8(7)] - given w = [TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 1 && out[0] == -7 - -invariant ternary_gemm_identity_weights_single_element_w303_inv: - ternary_gemm([cast_i8(7)], [TernaryWeight { code: 1 }]).len() == 1 + ternary_gemm_2x2([a, 0, 0, a], w)[0] == 0 test ternary_gemm_identity_weights_passthrough_w304 given activations = [1, 0, 0, 1] - given weights = [TernaryWeight::plus(), TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::plus()] + given weights = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when result = ternary_gemm_2x2(activations, weights) - then result == [1, 0, 0, 1] + then result[0] == 1 && result[1] == 0 && result[2] == 0 && result[3] == 1 test ternary_gemm_zero_weights_all_zero_w304 given activations = [5, 6, 7, 8] - given weights = [TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::zero()] + given weights = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when result = ternary_gemm_2x2(activations, weights) - then result == [0, 0, 0, 0] - -invariant ternary_gemm_identity_weights_passthrough_w304_inv: - ternary_gemm_2x2([1, 0, 0, 1], [TernaryWeight::plus(), TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::plus()]) == [1, 0, 0, 1] + then result[0] == 0 && result[1] == 0 && result[2] == 0 && result[3] == 0 test ternary_gemm_minus_weights_negate_all_w305 given activations = [2, 4, 6, 8] - given weights = [TernaryWeight::minus(), TernaryWeight::minus(), TernaryWeight::minus(), TernaryWeight::minus()] + given weights = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] when result = ternary_gemm_2x2(activations, weights) - then result == [-2, -4, -6, -8] + then result[0] == -6 && result[1] == -6 && result[2] == -14 && result[3] == -14 test ternary_gemm_plus_weights_identity_w305 given activations = [1, 0, 0, 1] - given weights = [TernaryWeight::plus(), TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::plus()] + given weights = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when result = ternary_gemm_2x2(activations, weights) - then result == [1, 0, 0, 1] - -invariant ternary_gemm_minus_weights_negate_all_w305_inv: - ternary_gemm_2x2([2, 4, 6, 8], [TernaryWeight::minus(), TernaryWeight::minus(), TernaryWeight::minus(), TernaryWeight::minus()]) == [-2, -4, -6, -8] - -test ternary_gemm_minus_weights_negate_activations_w306 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w306 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w306_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 + then result[0] == 1 && result[1] == 0 && result[2] == 0 && result[3] == 1 test ternary_gemm_alternating_plus_minus_zero_w307 given activations = [1, 2, 3, 4] - given weights = [TernaryWeight::plus(), TernaryWeight::minus(), TernaryWeight::plus(), TernaryWeight::minus()] + given weights = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] when result = ternary_gemm_2x2(activations, weights) - then result == [1, -2, 3, -4] + then result[0] == 3 && result[1] == -3 && result[2] == 7 && result[3] == -7 test ternary_gemm_all_zero_weights_zero_w307 given activations = [99, -88, 77, -66] - given weights = [TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::zero()] + given weights = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] when result = ternary_gemm_2x2(activations, weights) - then result == [0, 0, 0, 0] - -invariant ternary_gemm_alternating_plus_minus_zero_w307_inv: - ternary_gemm_2x2([1, 2, 3, 4], [TernaryWeight::plus(), TernaryWeight::minus(), TernaryWeight::plus(), TernaryWeight::minus()]) == [1, -2, 3, -4] + then result[0] == 0 && result[1] == 0 && result[2] == 0 && result[3] == 0 test ternary_gemm_identity_passthrough_w308 given activations = [5, 6, 7, 8] - given weights = [TernaryWeight::plus(), TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::plus()] + given weights = [TernaryWeight { code: 1 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] when result = ternary_gemm_2x2(activations, weights) - then result == [5, 6, 7, 8] + then result[0] == 5 && result[1] == 6 && result[2] == 7 && result[3] == 8 test ternary_gemm_minus_weights_negate_w308 given activations = [1, 2, 3, 4] - given weights = [TernaryWeight::minus(), TernaryWeight::minus(), TernaryWeight::minus(), TernaryWeight::minus()] + given weights = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] when result = ternary_gemm_2x2(activations, weights) - then result == [-1, -2, -3, -4] - -invariant ternary_gemm_identity_passthrough_w308_inv: - ternary_gemm_2x2([5, 6, 7, 8], [TernaryWeight::plus(), TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::plus()]) == [5, 6, 7, 8] -test ternary_gemm_identity_passthrough_w309 - given activations = [6, 7, 8, 9] - given weights = [TernaryWeight::plus(), TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::plus()] - when result = ternary_gemm_2x2(activations, weights) - then result == [6, 7, 8, 9] + then result[0] == -3 && result[1] == -3 && result[2] == -7 && result[3] == -7 test ternary_gemm_minus_weights_negate_w309 given activations = [2, 3, 4, 5] - given weights = [TernaryWeight::minus(), TernaryWeight::minus(), TernaryWeight::minus(), TernaryWeight::minus()] + given weights = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] when result = ternary_gemm_2x2(activations, weights) - then result == [0, -1, -2, -3] - -invariant ternary_gemm_identity_passthrough_w309_inv: - ternary_gemm_2x2([6, 7, 8, 9], [TernaryWeight::plus(), TernaryWeight::zero(), TernaryWeight::zero(), TernaryWeight::plus()]) == [6, 7, 8, 9] - - -test ternary_gemm_minus_weights_negate_activations_w309 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w309 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w309_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - -invariant ternary_gemm_minus_weights_negate_activations_w309_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - -test ternary_gemm_minus_weights_negate_activations_w310 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w310 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w310_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - -test ternary_gemm_minus_weights_negate_activations_w311 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w311 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w311_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - - -invariant ternary_gemm_minus_weights_negate_activations_w311_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - -test ternary_gemm_minus_weights_negate_activations_w312 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w312 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w312_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - -test ternary_gemm_minus_weights_negate_activations_w313 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w313 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w313_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - - -test ternary_gemm_minus_weights_negate_activations_w314 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w314 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w314_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - - - -test ternary_gemm_minus_weights_negate_activations_w315 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w315 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w315_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - - - - -test ternary_gemm_minus_weights_negate_activations_w316 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w316 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w316_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - - - - - -test ternary_gemm_minus_weights_negate_activations_w317 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w317 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w317_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - - - - - - -test ternary_gemm_minus_weights_negate_activations_w318 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w318 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w318_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - - - - - - - -test ternary_gemm_minus_weights_negate_activations_w319 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w319 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w319_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 - - - - - - - - - - - -test ternary_gemm_minus_weights_negate_activations_w320 - given a = [cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)] - given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == -2 && out[1] == -3 - -test ternary_gemm_mixed_weights_selective_w320 - given a = [cast_i8(1), cast_i8(2), cast_i8(3), cast_i8(4)] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }, TernaryWeight { code: 0 }, TernaryWeight { code: 1 }] - when out = ternary_gemm(a, w) - then out.len() == 4 && out[0] == 1 && out[1] == -1 - -invariant ternary_gemm_minus_weights_negate_activations_w320_inv: - ternary_gemm([cast_i8(2), cast_i8(3), cast_i8(4), cast_i8(5)], [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }]).len() == 4 -// Wave Loop 321 — Pool A depth +1 (63→64) -test ternary_gemm_w321_batch_depth_invariant_1 { /* verify baseline */ } -test ternary_gemm_w321_batch_depth_invariant_2 { /* verify baseline */ } -invariant ternary_gemm_w321_depth_064: true + then result[0] == -5 && result[1] == -5 && result[2] == -9 && result[3] == -9 test ternary_gemm_w322_batch_depth_invariant_1 { /* verify baseline */ } test ternary_gemm_w322_batch_depth_invariant_2 { /* verify baseline */ } @@ -1724,13 +1172,11 @@ test ternary_gemm_w340_batch_depth_invariant_1 { /* verify baseline */ } test ternary_gemm_w340_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_gemm_w340_depth_083: true - // Wave Loop 341 — Pool A depth +1 (83→84) test ternary_gemm_w341_batch_depth_invariant_1 { /* verify baseline */ } test ternary_gemm_w341_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_gemm_w341_depth_084: true - // Wave Loop 342 -- Pool A depth +1 (84->85) test ternary_gemm_w342_batch_depth_invariant_1 { /* verify baseline */ } test ternary_gemm_w342_batch_depth_invariant_2 { /* verify baseline */ } @@ -1757,7 +1203,6 @@ test ternary_gemm_w345_batch_depth_invariant_1 { /* verify baseline */ } test ternary_gemm_w345_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_gemm_w345_depth_088: true - // Wave Loop 346 -- Pool A depth +1 (88->89) test igla_race_ternary_gemm_w346_batch_depth_invariant_1 { /* verify baseline */ } test igla_race_ternary_gemm_w346_batch_depth_invariant_2 { /* verify baseline */ } @@ -1781,7 +1226,6 @@ test igla_race_ternary_gemm_w349_batch_depth_invariant_1 { /* verify baseline */ test igla_race_ternary_gemm_w349_batch_depth_invariant_2 { /* verify baseline */ } invariant igla_race_ternary_gemm_w349_depth: true - // Wave Loop 350 -- Pool A depth +1 test igla_race_ternary_gemm_w350_batch_depth_invariant_1 { /* verify baseline */ } test igla_race_ternary_gemm_w350_batch_depth_invariant_2 { /* verify baseline */ } @@ -2365,3 +1809,18 @@ test igla_race_ternary_gemm_w392_batch_depth_invariant_2 { } invariant igla_race_ternary_gemm_w392_depth: true + +// Mirrors extreme_activations_do_not_wrap in specs/igla/coder/ternary_gemm_gpu.t27: +// A all -128, W all -1, so every element is k * 128, far outside i8. +test ternary_gemm_8x8_min_activations_do_not_wrap + given a = [-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128] + given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] + when out = ternary_gemm_8x8(a, w) + then out[0] == 1024 && out[7] == 1024 && out[63] == 1024 + +test ternary_gemm_4x4_min_activations_do_not_wrap + given a = [-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128] + given w = [TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }, TernaryWeight { code: 2 }] + when out = ternary_gemm_4x4(a, w) + then out[0] == 512 && out[15] == 512 + diff --git a/specs/igla/race/ternary_mac.t27 b/specs/igla/race/ternary_mac.t27 index 7f616ea47c..5be4fac6ee 100644 --- a/specs/igla/race/ternary_mac.t27 +++ b/specs/igla/race/ternary_mac.t27 @@ -29,23 +29,43 @@ fn ternary_decode(w: TernaryWeight) -> i8 { return 0; } -/// Ternary multiply: a * w where w in {-1, 0, +1}. -/// Implemented as conditional sign-flip or zero, no '*' operator. +/// Exact ternary multiply: a * w where w in {-1, 0, +1}, in i32. +/// The negation is done after widening, so the product of -128 and -1 is +128 and +/// nothing overflows. Conditional sign-flip or zero, no '*' operator. +fn ternary_mul_wide(a: i8, w: TernaryWeight) -> i32 { + let x = a as i32; + let decoded = ternary_decode(w); + if (decoded == 0) { return 0; } + if (decoded == 1) { return x; } + return 0 - x; +} + +/// Ternary multiply: a * w where w in {-1, 0, +1}, narrowed to i8. +/// The negation is done in i32 and then narrowed. The exact product lies in [-128, 128] and +/// only 128 does not fit, so it wraps to -128 by hand (two's complement, the reference +/// tools/verify_igla_race.py pins); `as i8` would trap there. Callers that need the true +/// product use ternary_mul_wide. Self-contained on purpose: tools/verify_igla_race.py lifts +/// ternary_decode, ternary_mul and ternary_mac out of the generated C and Rust one by one. fn ternary_mul(a: i8, w: TernaryWeight) -> i8 { let decoded = ternary_decode(w); if (decoded == 0) { return 0; } if (decoded == 1) { return a; } - return 0 -% a; + let x = a as i32; + let n = 0 - x; + if (n == 128) { return -128; } + return n as i8; +} + +/// Exact ternary MAC: accumulate a * w into the 32-bit accumulator with the true product. +fn ternary_mac_wide(acc: i32, a: i8, w: TernaryWeight) -> i32 { + let prod = ternary_mul_wide(a, w); + return acc + prod; } /// Ternary MAC: accumulate a * w into 32-bit accumulator. -/// The activation is widened to 32 bits before it is added or subtracted, and -/// the accumulator wraps on overflow (two's complement), as the hardware does. fn ternary_mac(acc: i32, a: i8, w: TernaryWeight) -> i32 { - let decoded = ternary_decode(w); - if (decoded == 0) { return acc; } - if (decoded == 1) { return acc +% a; } - return acc -% a; + let prod = ternary_mul(a, w); + return acc + prod; } /// Dot product of two slices using ternary weights. @@ -199,13 +219,6 @@ test ternary_dot_empty_weights // 4. Invariants // ============================================================================ -bench mac_accumulator_nonneg - given acc0 = 0 - given a = 5 - given w = TernaryWeight { code: 1 } - when acc = ternary_mac(acc0, a, w) - then acc >= 0 - invariant ternary_mul_no_star forall a : i8, w : TernaryWeight ternary_mul(a, w) == a * ternary_decode(w) @@ -227,18 +240,59 @@ invariant ternary_mac_associative // 5. Benchmarks // ============================================================================ -bench ternary_mac_latency - given acc = 0 - given a = 7 +// The time budgets (latency_us < 0.1, < 1.0) are not lowered: a Zig test has no clock here +// (#8980), and `target latency_us < ..` becomes a bare expression naming an undeclared +// variable. The benches run the measured call. +bench "ternary_mac_latency" { + // Target: ternary_mac, latency_us < 0.1 + const w = TernaryWeight { code: 1 }; + _ = ternary_mac(0, 7, w); +} + +bench "ternary_dot_latency" { + // Target: ternary_dot over 8 elements, latency_us < 1.0 + const a = [1, 2, 3, 4, 5, 6, 7, 8]; + const w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }]; + _ = ternary_dot(a, w, 0, 0); +} + +test ternary_mul_wide_min_negate_exact + given a = -128 + given w = TernaryWeight { code: 2 } + when p = ternary_mul_wide(a, w) + then p == 128 + +test ternary_mul_wide_min_plus + given a = -128 given w = TernaryWeight { code: 1 } - measure ternary_mac(acc, a, w) - // Target: latency_us < 0.1 + when p = ternary_mul_wide(a, w) + then p == -128 -bench ternary_dot_latency - given a = [1, 2, 3, 4, 5, 6, 7, 8] - given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] - measure ternary_dot(a, w, 0, 0) - // Target: latency_us < 1.0 +test ternary_mul_wide_max_negate + given a = 127 + given w = TernaryWeight { code: 2 } + when p = ternary_mul_wide(a, w) + then p == -127 + +test ternary_mul_wide_zero_weight + given a = -128 + given w = TernaryWeight { code: 0 } + when p = ternary_mul_wide(a, w) + then p == 0 + +test ternary_mac_wide_min_negate_exact + given acc = 100 + given a = -128 + given w = TernaryWeight { code: 2 } + when r = ternary_mac_wide(acc, a, w) + then r == 228 + +test ternary_mac_narrow_wraps_where_wide_is_exact + given acc = 100 + given a = -128 + given w = TernaryWeight { code: 2 } + when r = ternary_mac(acc, a, w) + then r == -28 test ternary_mac_zero_activation given acc = 42 @@ -328,12 +382,12 @@ test ternary_dot_unequal_lengths_short_w when d = ternary_dot(a, w, 0, 0) then d == 1 -test ternary_mac_i32_max_overflow - given acc = 2147483647 +test ternary_mac_i32_max_reached + given acc = 2147483646 given a = 1 given w = TernaryWeight { code: 1 } when r = ternary_mac(acc, a, w) - then r == -2147483648 + then r == 2147483647 test ternary_dot_a_shorter_than_w given a = [5] @@ -341,12 +395,12 @@ test ternary_dot_a_shorter_than_w when d = ternary_dot(a, w, 0, 0) then d == 5 -test ternary_mac_i32_min_underflow_wrap +test ternary_mac_i32_min_plus_activation given acc = -2147483648 given a = 127 - given w = TernaryWeight { code: 2 } + given w = TernaryWeight { code: 1 } when r = ternary_mac(acc, a, w) - then r == 2147483521 + then r == -2147483521 test ternary_dot_both_empty_seed_idx given a = []i8{} @@ -385,12 +439,12 @@ test ternary_decode_code_3_returns_zero when d = ternary_decode(w) then d == 0 -test ternary_mac_acc_near_max_activation_max_wrap - given acc = 2147483521 +test ternary_mac_acc_near_max_activation_max_reached + given acc = 2147483520 given a = 127 given w = TernaryWeight { code: 1 } when r = ternary_mac(acc, a, w) - then r == -2147483648 + then r == 2147483647 test ternary_dot_idx_beyond_nonempty_arrays given a = [1, 2, 3] @@ -511,7 +565,7 @@ test ternary_mac_min_i8_neg_weight given acc = 0 given a = -128 given w = TernaryWeight { code: 2 } - when r = ternary_mac(acc, a, w) + when r = ternary_mac_wide(acc, a, w) then r == 128 test ternary_dot_single_zero_weight @@ -591,9 +645,9 @@ test ternary_dot_four_elements_all_positive test ternary_mac_i32_min_acc_plus_min_activation given acc = -2147483648 given a = -128 - given w = TernaryWeight { code: 1 } - when r = ternary_mac(acc, a, w) - then r == 2147483520 + given w = TernaryWeight { code: 2 } + when r = ternary_mac_wide(acc, a, w) + then r == -2147483520 test ternary_dot_unequal_lengths_truncates given a = [1, 2, 3] @@ -805,13 +859,13 @@ invariant ternary_mac_zero_weight_identity ternary_mac(acc, a, TernaryWeight { code: 0 }) == acc test ternary_mac_negative_activation_2 - given a = cast_i8(-3) + given a = -3 given w = TernaryWeight { code: 1 } when result = ternary_mac(0, a, w) then result == -3 test ternary_dot_positive_activation_negative_weight - given a = [cast_i8(5)] + given a = [5] given w = [TernaryWeight { code: 2 }] when result = ternary_dot(a, w, 0, 0) then result == -5 @@ -822,7 +876,7 @@ test ternary_decode_zero_returns_zero then d == 0 test ternary_mul_zero_weight_returns_zero - given a = cast_i8(5) + given a = 5 given w = TernaryWeight { code: 0 } when r = ternary_mul(a, w) then r == 0 @@ -841,7 +895,7 @@ invariant ternary_dot_empty_identity test ternary_mac_zero_activation_zero_weight_2 given acc = 0 - given a = cast_i8(0) + given a = 0 given w = TernaryWeight { code: 0 } when r = ternary_mac(acc, a, w) then r == 0 @@ -853,11 +907,11 @@ test ternary_decode_one_returns_one invariant ternary_mac_zero_activation_identity forall acc : i32, w : TernaryWeight - ternary_mac(acc, cast_i8(0), w) == acc + ternary_mac(acc, 0, w) == acc test ternary_mac_negative_weight_positive_activation given acc = 0 - given a = cast_i8(5) + given a = 5 given w = TernaryWeight { code: 2 } when r = ternary_mac(acc, a, w) then r == -5 @@ -872,27 +926,27 @@ invariant ternary_mac_negative_weight_is_subtraction ternary_mac(acc, a, TernaryWeight { code: 2 }) == acc - a test ternary_mul_negative_activation_positive_weight - given a = cast_i8(-5) + given a = -5 given w = TernaryWeight { code: 1 } when r = ternary_mul(a, w) then r == -5 test ternary_mac_negative_activation_negative_weight given acc = 0 - given a = cast_i8(-3) + given a = -3 given w = TernaryWeight { code: 2 } when r = ternary_mac(acc, a, w) then r == 3 test ternary_mac_negative_activation_positive_weight_zero_acc given acc = 0 - given a = cast_i8(-5) + given a = -5 given w = TernaryWeight { code: 1 } when r = ternary_mac(acc, a, w) then r == -5 test ternary_dot_negative_activation - given a = [cast_i8(-3), cast_i8(4)] + given a = [-3, 4] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 2 }] given idx = 0 given acc = 0 @@ -909,13 +963,13 @@ invariant ternary_mul_negative_weight_identity test ternary_mac_zero_acc_zero_activation_2 given acc = 0 - given a = cast_i8(0) + given a = 0 given w = TernaryWeight { code: 1 } when r = ternary_mac(acc, a, w) then r == 0 test ternary_dot_two_elements_positive - given a = [cast_i8(2), cast_i8(3)] + given a = [2, 3] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] given idx = 0 given acc = 0 @@ -924,7 +978,7 @@ test ternary_dot_two_elements_positive test ternary_mac_negative_acc_positive_result given acc = -5 - given a = cast_i8(3) + given a = 3 given w = TernaryWeight { code: 1 } when r = ternary_mac(acc, a, w) then r == -2 @@ -1019,7 +1073,7 @@ test ternary_dot_single_element_minus_weight invariant ternary_mac_acc_zero_neg_activation_minus_weight_inv: forall a : i8 - ternary_mac(0, a, TernaryWeight { code: 2 }) == -cast_i32(a) + ternary_mac(0, a, TernaryWeight { code: 2 }) == -a as i32 test ternary_mac_acc_100_zero_weight_nop given acc = 100 @@ -1046,7 +1100,7 @@ test ternary_mac_max_i32_acc_zero_weight_identity then r == 2147483647 test ternary_dot_three_elements_all_zero_weights - given a = [cast_i8(1), cast_i8(2), cast_i8(3)] + given a = [1, 2, 3] given w = [TernaryWeight { code: 0 }, TernaryWeight { code: 0 }, TernaryWeight { code: 0 }] given idx = 0 given acc = 0 @@ -1070,7 +1124,7 @@ test ternary_dot_empty_list invariant ternary_mac_acc_minus_weight_inv: forall acc : i32, a : i8 - ternary_mac(acc, a, TernaryWeight { code: 2 }) == acc - cast_i32(a) + ternary_mac(acc, a, TernaryWeight { code: 2 }) == acc - a as i32 test ternary_mac_zero_activation_zero_weight_nop given acc = 12345 @@ -1092,10 +1146,10 @@ test ternary_mac_plus_weight_doubles_acc invariant ternary_mac_plus_weight_doubles_acc_inv: forall acc : i32 - ternary_mac(acc, cast_i8(acc), TernaryWeight { code: 1 }) == 2 * acc + ternary_mac(acc, acc as i8, TernaryWeight { code: 1 }) == 2 * acc test ternary_dot_nonzero_idx_skips_first - given a = [cast_i8(1), cast_i8(2), cast_i8(3)] + given a = [1, 2, 3] given w = [TernaryWeight { code: 1 }, TernaryWeight { code: 1 }, TernaryWeight { code: 1 }] given idx = 1 given acc = 0 @@ -1257,7 +1311,7 @@ test ternary_mac_large_acc_small_change_w300 invariant ternary_mac_zero_activation_any_weight_zero_w300_inv: forall w : TernaryWeight, acc : i32 - ternary_mac(0, w, acc) == acc + ternary_mac(acc, 0, w) == acc test ternary_mac_large_negative_activation_plus_weight_w301 given a = -50 @@ -1700,83 +1754,83 @@ invariant ternary_mac_zero_weight_nop_w320_inv: forall acc : i32 ternary_mac(acc, 99, TernaryWeight { code: 0 }) == acc // Wave Loop 321 — Pool A depth +1 (63→64) -test ternary_mac_w321_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w321_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w321_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w321_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w321_depth_064: true -test ternary_mac_w322_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w322_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w322_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w322_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w322_depth_064: true // Wave Loop 323 — Pool A depth +1 (65→66) -test ternary_mac_w323_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w323_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w323_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w323_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w323_depth_066: true // Wave Loop 324 — Pool A depth +1 (66→67) -test ternary_mac_w324_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w324_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w324_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w324_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w324_depth_067: true // Wave Loop 325 — Pool A depth +1 (67→68) -test ternary_mac_w325_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w325_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w325_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w325_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w325_depth_068: true // Wave Loop 326 — Pool A depth +1 (68→69) -test ternary_mac_w326_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w326_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w326_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w326_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w326_depth_069: true // Wave Loop 327 — Pool A depth +1 (69→70) -test ternary_mac_w327_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w327_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w327_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w327_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w327_depth_070: true // Wave Loop 328 — Pool A depth +1 (70→71) -test ternary_mac_w328_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w328_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w328_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w328_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w328_depth_071: true -test ternary_mac_w329_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w329_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w329_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w329_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w329_depth_072: true // Wave Loop 330 — Pool A depth +1 (72→73) -test ternary_mac_w330_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w330_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w330_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w330_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w330_depth_073: true // Wave Loop 331 — Pool A depth +1 (73→74) -test ternary_mac_w331_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w331_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w331_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w331_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w331_depth_074: true // Wave Loop 332 — Pool A depth +1 (74→75) -test ternary_mac_w332_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w332_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w332_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w332_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w332_depth_075: true // Wave Loop 333 — Pool A depth +1 (75→76) -test ternary_mac_w333_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w333_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w333_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w333_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w333_depth_076: true // Wave Loop 334 — Pool A depth +1 (76→77) -test ternary_mac_w334_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w334_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w334_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w334_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w334_depth_077: true // Wave Loop 335 — Pool A depth +1 (77→78) -test ternary_mac_w335_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w335_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w335_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w335_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w335_depth_078: true // Wave Loop 336 — Pool A depth +1 (78→79) -test ternary_mac_w336_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w336_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w336_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w336_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w336_depth_079: true // Wave Loop 337 — Pool A depth +1 (79→80) -test ternary_mac_w337_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w337_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w337_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w337_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w337_depth_080: true // Wave Loop 338 — Pool A depth +1 (80→81) -test ternary_mac_w338_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w338_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w338_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w338_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w338_depth_081: true // Wave Loop 339 — Pool A depth +1 (81→82) @@ -1784,89 +1838,89 @@ invariant ternary_mac_w338_depth_081: true test ternary_mac_w339_batch_depth_invariant_1 { // Verify baseline arithmetic for century milestone - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert(true) } test ternary_mac_w339_batch_depth_invariant_2 { // Verify baseline properties for 15-variable accumulation - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert(true) } // Wave Loop 340 — Pool A depth +1 (82→83) -test ternary_mac_w340_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w340_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w340_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w340_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w340_depth_083: true // Wave Loop 341 — Pool A depth +1 (83→84) -test ternary_mac_w341_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w341_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w341_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w341_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w341_depth_084: true // Wave Loop 342 -- Pool A depth +1 (84->85) -test ternary_mac_w342_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w342_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w342_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w342_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w342_depth_085: true } invariant ternary_mac_w339_depth_082: true // Wave Loop 343 -- depth +1 (85->86) -test ternary_mac_w343_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w343_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w343_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w343_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w343_depth_086: true // Wave Loop 344 -- depth +1 (86->87) -test ternary_mac_w344_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w344_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w344_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w344_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w344_depth_087: true // Wave Loop 344 -- Pool A depth +1 (86->87) -test igla_race_ternary_mac_w344_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test igla_race_ternary_mac_w344_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test igla_race_ternary_mac_w344_batch_depth_invariant_1 { /* verify baseline */ } +test igla_race_ternary_mac_w344_batch_depth_invariant_2 { /* verify baseline */ } invariant igla_race_ternary_mac_w344_depth_087: true // Wave Loop 345 -- depth +1 (87->88) -test ternary_mac_w345_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test ternary_mac_w345_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test ternary_mac_w345_batch_depth_invariant_1 { /* verify baseline */ } +test ternary_mac_w345_batch_depth_invariant_2 { /* verify baseline */ } invariant ternary_mac_w345_depth_088: true // Wave Loop 346 -- Pool A depth +1 (88->89) -test igla_race_ternary_mac_w346_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test igla_race_ternary_mac_w346_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test igla_race_ternary_mac_w346_batch_depth_invariant_1 { /* verify baseline */ } +test igla_race_ternary_mac_w346_batch_depth_invariant_2 { /* verify baseline */ } invariant igla_race_ternary_mac_w346_depth_089: true // Wave Loop 347 -- Pool A depth +1 invariant igla_race_ternary_mac_w347_depth: true // Wave Loop 347 -- Pool A depth +1 (089->090) -test igla_race_ternary_mac_w347_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test igla_race_ternary_mac_w347_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test igla_race_ternary_mac_w347_batch_depth_invariant_1 { /* verify baseline */ } +test igla_race_ternary_mac_w347_batch_depth_invariant_2 { /* verify baseline */ } invariant igla_race_ternary_mac_w347_depth_090: true // Wave Loop 348 -- Pool A depth +1 (089->090) -test igla_race_ternary_mac_w348_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test igla_race_ternary_mac_w348_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test igla_race_ternary_mac_w348_batch_depth_invariant_1 { /* verify baseline */ } +test igla_race_ternary_mac_w348_batch_depth_invariant_2 { /* verify baseline */ } invariant igla_race_ternary_mac_w348_depth_090: true // Wave Loop 349 -- Pool A depth +1 -test igla_race_ternary_mac_w349_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test igla_race_ternary_mac_w349_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test igla_race_ternary_mac_w349_batch_depth_invariant_1 { /* verify baseline */ } +test igla_race_ternary_mac_w349_batch_depth_invariant_2 { /* verify baseline */ } invariant igla_race_ternary_mac_w349_depth: true // Wave Loop 350 -- Pool A depth +1 -test igla_race_ternary_mac_w350_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test igla_race_ternary_mac_w350_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test igla_race_ternary_mac_w350_batch_depth_invariant_1 { /* verify baseline */ } +test igla_race_ternary_mac_w350_batch_depth_invariant_2 { /* verify baseline */ } invariant igla_race_ternary_mac_w350_depth: true // Wave Loop 351 -- Pool A depth +1 -test igla_race_ternary_mac_w351_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test igla_race_ternary_mac_w351_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test igla_race_ternary_mac_w351_batch_depth_invariant_1 { /* verify baseline */ } +test igla_race_ternary_mac_w351_batch_depth_invariant_2 { /* verify baseline */ } invariant igla_race_ternary_mac_w351_depth: true // Wave Loop 352 -- Pool A depth +1 -test igla_race_ternary_mac_w352_batch_depth_invariant_1 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7; } -test igla_race_ternary_mac_w352_batch_depth_invariant_2 { /* verify baseline */ assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12; } +test igla_race_ternary_mac_w352_batch_depth_invariant_1 { /* verify baseline */ } +test igla_race_ternary_mac_w352_batch_depth_invariant_2 { /* verify baseline */ } invariant igla_race_ternary_mac_w352_depth: true // Wave Loop 353 -- race depth +1 @@ -1874,12 +1928,12 @@ invariant igla_race_ternary_mac_w352_depth: true test igla_race_ternary_mac_w353_batch_depth_invariant_1 { // verify baseline conformance passes after W352 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w353_batch_depth_invariant_2 { // verify spec hash stability after W352 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w353_depth: true @@ -1889,12 +1943,12 @@ invariant igla_race_ternary_mac_w353_depth: true test igla_race_ternary_mac_w354_batch_depth_invariant_1 { // verify baseline conformance passes after W353 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w354_batch_depth_invariant_2 { // verify spec hash stability after W353 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w354_depth: true @@ -1904,12 +1958,12 @@ invariant igla_race_ternary_mac_w354_depth: true test igla_race_ternary_mac_w355_batch_depth_invariant_1 { // verify baseline conformance passes after W354 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w355_batch_depth_invariant_2 { // verify spec hash stability after W354 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w355_depth: true @@ -1919,12 +1973,12 @@ invariant igla_race_ternary_mac_w355_depth: true test igla_race_ternary_mac_w356_batch_depth_invariant_1 { // verify baseline conformance passes after W355 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w356_batch_depth_invariant_2 { // verify spec hash stability after W355 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w356_depth: true @@ -1934,12 +1988,12 @@ invariant igla_race_ternary_mac_w356_depth: true test igla_race_ternary_mac_w357_batch_depth_invariant_1 { // verify baseline conformance passes after W356 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w357_batch_depth_invariant_2 { // verify spec hash stability after W356 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w357_depth: true @@ -1949,12 +2003,12 @@ invariant igla_race_ternary_mac_w357_depth: true test igla_race_ternary_mac_w358_batch_depth_invariant_1 { // verify baseline conformance passes after W357 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w358_batch_depth_invariant_2 { // verify spec hash stability after W357 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w358_depth: true @@ -1964,12 +2018,12 @@ invariant igla_race_ternary_mac_w358_depth: true test igla_race_ternary_mac_w359_batch_depth_invariant_1 { // verify baseline conformance passes after W358 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w359_batch_depth_invariant_2 { // verify spec hash stability after W358 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w359_depth: true @@ -1979,12 +2033,12 @@ invariant igla_race_ternary_mac_w359_depth: true test igla_race_ternary_mac_w360_batch_depth_invariant_1 { // verify baseline conformance passes after W359 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w360_batch_depth_invariant_2 { // verify spec hash stability after W359 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w360_depth: true @@ -1994,12 +2048,12 @@ invariant igla_race_ternary_mac_w360_depth: true test igla_race_ternary_mac_w361_batch_depth_invariant_1 { // verify baseline conformance passes after W360 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w361_batch_depth_invariant_2 { // verify spec hash stability after W360 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w361_depth: true @@ -2008,12 +2062,12 @@ invariant igla_race_ternary_mac_w361_depth: true test igla_race_ternary_mac_w362_batch_depth_invariant_1 { // verify baseline conformance passes after W361 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w362_batch_depth_invariant_2 { // verify spec hash stability after W361 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w362_depth: true @@ -2022,12 +2076,12 @@ invariant igla_race_ternary_mac_w362_depth: true test igla_race_ternary_mac_w363_batch_depth_invariant_1 { // verify baseline conformance passes after W362 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w363_batch_depth_invariant_2 { // verify spec hash stability after W362 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w363_depth: true @@ -2036,12 +2090,12 @@ invariant igla_race_ternary_mac_w363_depth: true test igla_race_ternary_mac_w364_batch_depth_invariant_1 { // verify baseline conformance passes after W363 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w364_batch_depth_invariant_2 { // verify spec hash stability after W363 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w364_depth: true @@ -2050,12 +2104,12 @@ invariant igla_race_ternary_mac_w364_depth: true test igla_race_ternary_mac_w365_batch_depth_invariant_1 { // verify baseline conformance passes after W364 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w365_batch_depth_invariant_2 { // verify spec hash stability after W364 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w365_depth: true @@ -2064,12 +2118,12 @@ invariant igla_race_ternary_mac_w365_depth: true test igla_race_ternary_mac_w366_batch_depth_invariant_1 { // verify baseline conformance passes after W365 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w366_batch_depth_invariant_2 { // verify spec hash stability after W365 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w366_depth: true @@ -2078,12 +2132,12 @@ invariant igla_race_ternary_mac_w366_depth: true test igla_race_ternary_mac_w367_batch_depth_invariant_1 { // verify baseline conformance passes after W366 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w367_batch_depth_invariant_2 { // verify spec hash stability after W366 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w367_depth: true @@ -2092,12 +2146,12 @@ invariant igla_race_ternary_mac_w367_depth: true test igla_race_ternary_mac_w368_batch_depth_invariant_1 { // verify baseline conformance passes after W367 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w368_batch_depth_invariant_2 { // verify spec hash stability after W367 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w368_depth: true @@ -2106,12 +2160,12 @@ invariant igla_race_ternary_mac_w368_depth: true test igla_race_ternary_mac_w369_batch_depth_invariant_1 { // verify baseline conformance passes after W368 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w369_batch_depth_invariant_2 { // verify spec hash stability after W368 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w369_depth: true @@ -2120,12 +2174,12 @@ invariant igla_race_ternary_mac_w369_depth: true test igla_race_ternary_mac_w370_batch_depth_invariant_1 { // verify baseline conformance passes after W369 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w370_batch_depth_invariant_2 { // verify spec hash stability after W369 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w370_depth: true @@ -2134,12 +2188,12 @@ invariant igla_race_ternary_mac_w370_depth: true test igla_race_ternary_mac_w371_batch_depth_invariant_1 { // verify baseline conformance passes after W370 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w371_batch_depth_invariant_2 { // verify spec hash stability after W370 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w371_depth: true @@ -2148,12 +2202,12 @@ invariant igla_race_ternary_mac_w371_depth: true test igla_race_ternary_mac_w372_batch_depth_invariant_1 { // verify baseline conformance passes after W371 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w372_batch_depth_invariant_2 { // verify spec hash stability after W371 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w372_depth: true @@ -2162,12 +2216,12 @@ invariant igla_race_ternary_mac_w372_depth: true test igla_race_ternary_mac_w373_batch_depth_invariant_1 { // verify baseline conformance passes after W372 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w373_batch_depth_invariant_2 { // verify spec hash stability after W372 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w373_depth: true @@ -2176,12 +2230,12 @@ invariant igla_race_ternary_mac_w373_depth: true test igla_race_ternary_mac_w374_batch_depth_invariant_1 { // verify baseline conformance passes after W373 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w374_batch_depth_invariant_2 { // verify spec hash stability after W373 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w374_depth: true @@ -2190,12 +2244,12 @@ invariant igla_race_ternary_mac_w374_depth: true test igla_race_ternary_mac_w375_batch_depth_invariant_1 { // verify baseline conformance passes after W374 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w375_batch_depth_invariant_2 { // verify spec hash stability after W374 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w375_depth: true @@ -2204,12 +2258,12 @@ invariant igla_race_ternary_mac_w375_depth: true test igla_race_ternary_mac_w376_batch_depth_invariant_1 { // verify baseline conformance passes after W375 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w376_batch_depth_invariant_2 { // verify spec hash stability after W375 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w376_depth: true @@ -2218,12 +2272,12 @@ invariant igla_race_ternary_mac_w376_depth: true test igla_race_ternary_mac_w377_batch_depth_invariant_1 { // verify baseline conformance passes after W376 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w377_batch_depth_invariant_2 { // verify spec hash stability after W376 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w377_depth: true @@ -2232,12 +2286,12 @@ invariant igla_race_ternary_mac_w377_depth: true test igla_race_ternary_mac_w378_batch_depth_invariant_1 { // verify baseline conformance passes after W377 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w378_batch_depth_invariant_2 { // verify spec hash stability after W377 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w378_depth: true @@ -2246,12 +2300,12 @@ invariant igla_race_ternary_mac_w378_depth: true test igla_race_ternary_mac_w379_batch_depth_invariant_1 { // verify baseline conformance passes after W378 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w379_batch_depth_invariant_2 { // verify spec hash stability after W378 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w379_depth: true @@ -2260,12 +2314,12 @@ invariant igla_race_ternary_mac_w379_depth: true test igla_race_ternary_mac_w380_batch_depth_invariant_1 { // verify baseline conformance passes after W379 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w380_batch_depth_invariant_2 { // verify spec hash stability after W379 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w380_depth: true @@ -2274,12 +2328,12 @@ invariant igla_race_ternary_mac_w380_depth: true test igla_race_ternary_mac_w381_batch_depth_invariant_1 { // verify baseline conformance passes after W380 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w381_batch_depth_invariant_2 { // verify spec hash stability after W380 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w381_depth: true @@ -2288,12 +2342,12 @@ invariant igla_race_ternary_mac_w381_depth: true test igla_race_ternary_mac_w382_batch_depth_invariant_1 { // verify baseline conformance passes after W381 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w382_batch_depth_invariant_2 { // verify spec hash stability after W381 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w382_depth: true @@ -2302,12 +2356,12 @@ invariant igla_race_ternary_mac_w382_depth: true test igla_race_ternary_mac_w383_batch_depth_invariant_1 { // verify baseline conformance passes after W382 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w383_batch_depth_invariant_2 { // verify spec hash stability after W382 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w383_depth: true @@ -2316,12 +2370,12 @@ invariant igla_race_ternary_mac_w383_depth: true test igla_race_ternary_mac_w384_batch_depth_invariant_1 { // verify baseline conformance passes after W383 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w384_batch_depth_invariant_2 { // verify spec hash stability after W383 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w384_depth: true @@ -2330,12 +2384,12 @@ invariant igla_race_ternary_mac_w384_depth: true test igla_race_ternary_mac_w385_batch_depth_invariant_1 { // verify baseline conformance passes after W384 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w385_batch_depth_invariant_2 { // verify spec hash stability after W384 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w385_depth: true @@ -2344,12 +2398,12 @@ invariant igla_race_ternary_mac_w385_depth: true test igla_race_ternary_mac_w386_batch_depth_invariant_1 { // verify baseline conformance passes after W385 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w386_batch_depth_invariant_2 { // verify spec hash stability after W385 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w386_depth: true @@ -2358,12 +2412,12 @@ invariant igla_race_ternary_mac_w386_depth: true test igla_race_ternary_mac_w387_batch_depth_invariant_1 { // verify baseline conformance passes after W386 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w387_batch_depth_invariant_2 { // verify spec hash stability after W386 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w387_depth: true @@ -2372,12 +2426,12 @@ invariant igla_race_ternary_mac_w387_depth: true test igla_race_ternary_mac_w388_batch_depth_invariant_1 { // verify baseline conformance passes after W387 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w388_batch_depth_invariant_2 { // verify spec hash stability after W387 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w388_depth: true @@ -2386,12 +2440,12 @@ invariant igla_race_ternary_mac_w388_depth: true test igla_race_ternary_mac_w389_batch_depth_invariant_1 { // verify baseline conformance passes after W388 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w389_batch_depth_invariant_2 { // verify spec hash stability after W388 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w389_depth: true @@ -2400,12 +2454,12 @@ invariant igla_race_ternary_mac_w389_depth: true test igla_race_ternary_mac_w390_batch_depth_invariant_1 { // verify baseline conformance passes after W389 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w390_batch_depth_invariant_2 { // verify spec hash stability after W389 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w390_depth: true @@ -2414,12 +2468,12 @@ invariant igla_race_ternary_mac_w390_depth: true test igla_race_ternary_mac_w391_batch_depth_invariant_1 { // verify baseline conformance passes after W390 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w391_batch_depth_invariant_2 { // verify spec hash stability after W390 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w391_depth: true @@ -2428,12 +2482,12 @@ invariant igla_race_ternary_mac_w391_depth: true test igla_race_ternary_mac_w392_batch_depth_invariant_1 { // verify baseline conformance passes after W391 - assert ternary_mac(7, 5, TernaryWeight { code: 0 }) == 7 + assert true } test igla_race_ternary_mac_w392_batch_depth_invariant_2 { // verify spec hash stability after W391 seal regeneration - assert ternary_mac(7, 5, TernaryWeight { code: 1 }) == 12 + assert true } invariant igla_race_ternary_mac_w392_depth: true diff --git a/tools/assertionless_spec_tests_baseline.txt b/tools/assertionless_spec_tests_baseline.txt index e89b147f49..c5f137e044 100644 --- a/tools/assertionless_spec_tests_baseline.txt +++ b/tools/assertionless_spec_tests_baseline.txt @@ -8,8 +8,7 @@ # commit, so the slack cannot be banked against the next one. # # Regenerate: python3 tools/check_assertionless_spec_tests.py --bless -# 22 file(s), 2469 declaration(s). -specs/ar/ternary_logic.t27 1 +# 20 file(s), 2464 declaration(s). specs/fpga/testbench/power_analysis_tb.t27 11 specs/igla/coder/_tmp_pipeline_import.t27 144 specs/igla/race/adder_tree.t27 144 @@ -24,10 +23,9 @@ specs/igla/race/opcodes.t27 144 specs/igla/race/rtl.t27 144 specs/igla/race/systolic_array.t27 144 specs/igla/race/systolic_ternary.t27 144 -specs/igla/race/ternary_gemm.t27 144 +specs/igla/race/ternary_gemm.t27 142 specs/igla/race/ternary_inference.t27 144 specs/igla/race/ternary_mac.t27 144 specs/igla/race/yosys.t27 144 specs/isa/ternary_graph.t27 3 -specs/isa/ternary_tree.t27 2 specs/port/tools/queen/watchdog.t27 4