提交记录 119096


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_cc_v41_agg1 mmms4k. 测测你的短整数矩阵乘法-4k Accepted 100 532.648 ms 134252 KB C++17 58.07 KB
提交时间 评测时间
2026-10-01 20:40:41 2026-10-01 20:40:45
// ===== [s4cu-BANDSTAGE] mmms4k pack 相:把源读从"8 KB 跨步、每行 64 B"改成行带序(64 行整带顺序读)+ 1 MB 密铺 64x64 暂存窗 =====
// ===== REFERENCES =====
// [1] 本账号现役最好件 **#119087** <https://duck.ac/submission/119087>(529.939210 ms = 本题 mine)
//     —— 本件正文 = 该提交正文的**逐字节副本**,**唯一改动** = 下方"思路"段的 (a)(b)(c) 三处(pack 相遍历与读序;
//     mul/combine/root_fuse/叶内核/emit_root64 **一字未动**)。
// [2] 本账号 **#118894**(s4cl_ 席,530.080855 ms)与 #118374/#118809/#118817(duck.ac 用户 **pdoom**,本引擎原始作者)
//     —— 正文 Credit 段**逐字保留、未改一字**;pack/emit/叶的算术为上述正文**直接复制**。
// [3] 本席自造台架 `work/s4ct_tmp/s4ct_pk3.cpp`(s4ct_ 席,复红后第 49 席;**直接复制**其 pack-only 同批多臂台骨架、
//     ck_all()、驱动与统计口径到 `work/s4cu_tmp/s4cu_pk5.cpp`,再在其上加入"行带序暂存"臂)。
// [4] Oded Schwartz & Noa Vaknin, SIAM J. Sci. Comput. (2023), doi 10.1137/22M1502719(exact 七乘十二加 alternative-basis 分解)
//     —— 正文内已署名;仅参考其思想,未逐字移植。
// 合规:duck.ac 提交正文按站点规则公开可见;原提交无独立许可证声明,按 RULES.md 第 3 节署名作者账号与原地址。
// ======================
// ===== 思路 =====
// 【派单】把 pack 的读序从"8 KB 跨步、每行 64 B"改成**行带序**(按 64 行整带扫满 4096 列 = 顺序读),用 ~1 MB 打包中间缓冲。
// 【机理先判(本席自造仪器 `work/s4cu_tmp/s4cu_mech.cpp`,同字节数三序对照 + 同 store 流)】本机 TSC 1.7958 GHz,33.55 MB:
//   跨步序纯读 **9.09e6 拍**(= 6.6 GB/s)· 全顺序纯读 **4.82e6 拍**(= 12.5 GB/s,**1.89×**)· 行带序(64 行带顺序读)
//   ≡ 全顺序(行内连续,带就是连续 512 KB);加上 pack 的 store 流(1024 单元 x 58 240 B):跨步 30.8e6 ↔ **行带+密铺暂存 23.8e6
//   (−22.8%)**,而"读窗内命中"上界(无 copy)= 18.4e6 ⇒ **判据成立:读的暴露来自 8 KB 跨步与 store 流争用**。
// 【改动】(a) 遍历:`pack_root` 的四叉递归 → **行带主序**:R = 0,64,…,1984 逐带;每带把源矩阵 [R,R+64) 与 [R+2048,R+2112)
//   两行带(各 4096 列)**顺序读入** 128 个密铺 64x64 tile(1 MB 静态窗 stag);(b) 叶读:从该窗按 **stride 64** 读
//   (32x32 子叶、transformed 的 p-32*ST/p-32 均仍在同一 64x64 块内,语义与原 4096 跨步版逐位等价);
//   (c) 目的偏移:原四叉递归的 offset 由**闭式**算出(`work/s4cu_tmp/s4cu_offchk.cpp` 对 1024 个 64-tile **穷举比对递归,0 失配**)。
//   跨带依赖(k=3 的 High 发射需同区 k=1 的 high_left)用 16 槽 532 KB 缓冲跨带保持;发射函数 `emit_root64` 未改。
// 【判题机同批实测(本席自定义测试 `s4cu_pk5.cpp`,i3-8100 3.6008 GHz,0/1 交替 8 跑)】
//   基座温 **60.060 / 60.176 / 60.061e6 拍** ↔ 行带序 **41.966 / 42.063 / 42.047e6 拍** ⇒ **−18.06e6 拍 = −30.1%(5.02 ms)**;
//   ck 两侧均 = **30d50239716f226d**(逐位同,判题机同批实测)· 冷首跑 74.43e6(= 基座冷,含目标页首触)。
// 【本机全引擎同批 A/B(本席 `s4cu_e_base` ↔ `s4cu_e_stag`,交替 3 轮,s4ct_drv_full 驱动)】
//   基座 1487.5 / 1481.9 / 1464.2e6 ↔ 本件 1479.3 / **1448.4 / 1451.4e6**(−18.2e6,与 pack-only 台 Δ 同量级);
//   两侧 C 哈希均 = **94243319c5501b22**(逐位同)。
// 【闸门】ck 逐位同 ✓(本机全引擎 + 判题机 pack-only 两侧)· 真随机档(xorshift 填满 A/B)✓ · 同装填器 ✓ · 同批锚 0/1 交替 ✓
//   · 单变量(仅 pack 相读序/遍历/暂存,乘法与重建未动)✓ · 源码 56 938 字符 ≤ 102 400 ✓ · `^int main` = 0 ✓ · 保值型(不改输出)。
// ============================================================================================
// ===== [s4ct-PKLEAF64] mmms4k 叶内源预取(单变量:pack() 左叶循环体首加 8 条 __builtin_prefetch)=====
// ===== REFERENCES =====
// [1] 本账号现役最好件 **#118894** <https://duck.ac/submission/118894>(530.080855 ms = 本题 mine)
//     —— 本件正文 = 该提交正文**逐字节**,**唯一改动** = 下方"思路"段指名的那一处(叶内 8 条纯预取提示)。
// [2] duck.ac 用户 **pdoom** #118374/#118809/#118817(本引擎原始作者)—— 正文 Credit 段逐字保留、未改一字。
// [3] Oded Schwartz & Noa Vaknin, SIAM J. Sci. Comput. (2023), doi 10.1137/22M1502719
//     (exact 七乘十二加 alternative-basis 分解)—— 正文内已署名;仅参考其思想,未逐字移植。
// 合规:duck.ac 提交正文按站点规则公开可见;原提交无独立许可证声明,按 RULES.md 第 3 节署名作者账号与原地址。
// ======================
// ===== 思路 =====
// 【装置】`work/s4ct_tmp/s4ct_pk3.cpp`(判题机自定义测试 2 发):只跑 pack_root<false>(A)+pack_root<true>(B);
//   各臂用**编译期模板参数**实例化(零运行期分支、同一二进制、同一页集、同一漂移、同批锚 = 同文件 arm0)。
//   ck = 11 个打包槽(ar 4 + br 7) + C 的 3 个槽 的 FNV;**在 arm 0/4/8/12/64/128/256 上逐位相同** ⇒ 真单变量、逐位无害。
// 【判题机 pack 相实测(3.6008 GHz TSC)】冷 **60.68e6 拍 = 16.9 ms** · 温 **40.79e6 拍 = 11.3 ms**(后者−前者 = 缺页税 19.9e6 拍 = 5.5 ms)。
// 【拆解(温)】纯计算 **16.28e6(40%)** · 源读 **20.7e6**(广播读臂)/ **21.6e6**(同页读臂) · 目标写 **6.5e6**(同页写臂)。
// 【★ "串行暴露的源读"定量判决】另加一条**纯读内核** `PAT`:用与 pack **逐字节相同**的访问序读同样的 64 MB、
//   不写、不算 —— 判题机 **PAT = 7.65e6 拍 = 30.1 GB/s**;而同一 64 MB 读**在 pack 内部**要 **20.7~21.6e6 拍 = 9.6~10.0 GB/s**
//   ⇒ **读流被 pack 的 store 流/计算放大了 2.7~2.8×**。同 probe 的混合流墙 `WALL`(288 MB)= 23.4 GB/s。
//   ⇒ 判决:源读**确实是被暴露的**(其自身模式可达 30 GB/s,pack 内只有 1/3),**但其暴露量来自 LSU/LFB/DRAM 调度争用,
//   不是"预取距离不够"** —— 见下剂量表:加深预取只回收 3%。
// 【本件改动】`pack()` 左叶(32x32)循环体首插入 8 条 `__builtin_prefetch`:把**行 i+4..i+7 在 k 与 k+16 两个列块**的
//   源行提前拉入(提前量 = 4 个 i 步 × 2 个 k 块 ≈ 8 次迭代)。不改任何值、任何地址、任何次序。
// 【判题机剂量表(同 probe,2 样本/臂,臂内散布 ≤0.12%)】arm4(提前 4 行×1 列块)**−0.75e6(−1.8%)** ·
//   **arm64(提前 4 行×2 列块)= 本件 −1.35e6 拍 = −3.3%(0.37 ms)** · arm128(64x64 粗块整块预取)−0.25e6 ·
//   arm256(pack_four 四粗块全预取)**+0.82e6(负)** · arm8(k 外/i 内换序,逐位同)**+6.3e6(负)**。
//   ⇒ 预取有**最优点**,过深即被 LFB 饱和反噬;**本件 = 实测最优臂**。
// 【本机同批 A/B(8 跑交替,两件 ck 均 = 94243319c5501b22 逐位同,n=4096)】基座中位 1490.6e6 拍 ↔ 本件中位 1476.2e6 拍(−1.0%)。
// 【闸门】ck 逐位同 ✓ · 真随机档(xorshift 填满 A/B)✓ · 同装填器(ref/gcc9/g9.sh -O2 -std=c++17 -static -U_FORTIFY_SOURCE)✓
//   · 同批锚 ✓ · `^int main` = 0 ✓ · 源码 50 959 字符 ≤ 102 400 ✓ · 本件为**保值型**臂(不改值 ⇒ ck 判据 = "相同")。
// ============================================================================================
/*
Credit:
pdoom #118374, https://duck.ac/submission/118374 : exact BASE32 engine,
4-row simultaneous product scheduling, one fully unrolled asm body, and
coarse64 root packing with complete NT cache-line streams.
saffah_cc_v41_agg1 #118613, https://duck.ac/submission/118613 : ROOT_PAD
and workspace address phases, adapted here to the BASE32 recursive graph.
saffah_cc_v41_agg1 #118236, https://duck.ac/submission/118236 : three-madd
scheduling, fused four-quadrant root output, C root raw-input reuse, and
shift/blend truncation with deferred inverse word permutation.
Oded Schwartz and Noa Vaknin, SIAM J. Sci. Comput. (2023), (3.1): exact
seven-product, twelve-add alternative-basis decomposition over a ring.
https://epubs.siam.org/doi/10.1137/22M1502719
Retained lineage:
pdoom #86352 : mod65536 engine and pair-dot products; #112312 : fused root
packing, retired root slot reuse, complete cache-line streams and leaf pads;
#117569 : SIMD-native output and delayed root decode; #118412 : bottom-layer
alternative basis fused at both endpoints and skipping logical leaf padding.
saffah_cc_v41_agg1 #112006/#117247 : peeled initial pair, operand/output
packing, cache phases, three-row scheduling, and compiler options.
saffah_codex_6s_agg2 #110387/#102935 : fused reconstruction, constant
recursion and instruction order. saffah_cc_v41_260924 #96771 : cache phases.
New combination:
Use 32x32 arithmetic leaves and N=64 plus N=128 alternative-basis products.
Apply the input map in raw 32x32 leaf loads, and the inverse output map in
root reconstruction. Internal arithmetic skips the 16-word physical gap;
coarse64 root streams retain it to finish every 64-byte cache line.
Use C's retired tail as the recursive workspace before final C writeback.
Every output is exact modulo65536, independently of input distribution.
Specialized to the stated n=4096 with separate aligned A, B and C buffers.
*/
#define ALTMAX 128
#define ROOT_PAD 160
#pragma GCC optimize("O3,unroll-loops,web,rename-registers")
#pragma GCC target("avx2")
#include <immintrin.h>
#include <stdint.h>
#include <string.h>

asm(".macro vzeroupper\n.endm\n");

#ifndef TILE_PAD
#define TILE_PAD 16
#endif
#ifndef BASE
#define BASE (1 << 5)
#endif
using U = uint16_t;
static constexpr int MAXN = 4096;
alignas(4096) static U pa_[MAXN * MAXN + (MAXN/BASE)*(MAXN/BASE)*TILE_PAD + 8192], pb_[MAXN * MAXN + (MAXN/BASE)*(MAXN/BASE)*TILE_PAD + 8192];
alignas(4096) static U pc_[MAXN * MAXN + (MAXN/BASE)*(MAXN/BASE)*TILE_PAD + 8192], ws_[MAXN * MAXN + (MAXN/BASE)*(MAXN/BASE)*TILE_PAD + 8192];

static U *pa = pa_ + 1024, *pb = pb_ + 1024, *pc = pc_ + 0, *ws = ws_ + 1024;
static U *final_out;
static inline __m256i ld(const U *p) {
    return _mm256_load_si256((const __m256i *)p);
}
static inline void st(U *p, __m256i x) {
    _mm256_store_si256((__m256i *)p, x);
}

// The recursive quadrant layout makes every Strassen addition contiguous.
static const U *raw_basis_input;
static inline __m256i raw_basis_low32(const U *p,bool transformed) {
 __m256i v=_mm256_loadu_si256((const __m256i*)p);
 if(transformed) v=_mm256_add_epi16(v,_mm256_sub_epi16(
  _mm256_loadu_si256((const __m256i*)(p-32*4096)),
  _mm256_loadu_si256((const __m256i*)(p-32))));
 return v;
}
static inline __m128i raw_basis_low16(const U *p,bool transformed) {
 __m128i v=_mm_loadu_si128((const __m128i*)p);
 if(transformed) v=_mm_add_epi16(v,_mm_sub_epi16(
  _mm_loadu_si128((const __m128i*)(p-32*4096)),
  _mm_loadu_si128((const __m128i*)(p-32))));
 return v;
}
static inline __m256i raw_basis32(const U *p,int flags) {
 __m256i v=raw_basis_low32(p,flags&1);
 if(flags&2) v=_mm256_add_epi16(v,_mm256_sub_epi16(
  raw_basis_low32(p-64*4096,flags&1),raw_basis_low32(p-64,flags&1)));
 return v;
}
static inline __m128i raw_basis16(const U *p,int flags) {
 __m128i v=raw_basis_low16(p,flags&1);
 if(flags&2) v=_mm_add_epi16(v,_mm_sub_epi16(
  raw_basis_low16(p-64*4096,flags&1),raw_basis_low16(p-64,flags&1)));
 return v;
}
static void pack(U *d, const U *s, int n, int stride, bool right) {
    if (n > BASE) {
        int h = n / 2, q=h*h+(h/BASE)*(h/BASE)*TILE_PAD;
        pack(d, s, h, stride, right);
        pack(d + q, s + h, h, stride, right);
        pack(d + 2*q, s + h*stride, h, stride, right);
        pack(d + 3*q, s + h*stride + h, h, stride, right);
    } else if (!right) {
        const int transformed=(((s-raw_basis_input)&32) && ((s-raw_basis_input)&(32*4096)))?1:0;
        for(int i=0;i<n;i+=4) for(int k=0;k<n;k+=16) {
            { int i2=(i+4)&31;  /* s4ct-PKLEAF64: rows i+4..i+7, both k blocks */
              __builtin_prefetch(s+i2*stride+k);__builtin_prefetch(s+(i2+1)*stride+k);
              __builtin_prefetch(s+i2*stride+k+16);__builtin_prefetch(s+(i2+1)*stride+k+16);
              __builtin_prefetch(s+(i2+2)*stride+k);__builtin_prefetch(s+(i2+3)*stride+k);
              __builtin_prefetch(s+(i2+2)*stride+k+16);__builtin_prefetch(s+(i2+3)*stride+k+16); }
            __m256i a=raw_basis32(s+i*stride+k,transformed), b=raw_basis32(s+(i+1)*stride+k,transformed);
            __m256i c=raw_basis32(s+(i+2)*stride+k,transformed), e=raw_basis32(s+(i+3)*stride+k,transformed);
            __m256i t0=_mm256_unpacklo_epi32(a,b),t1=_mm256_unpacklo_epi32(c,e);
            __m256i t2=_mm256_unpackhi_epi32(a,b),t3=_mm256_unpackhi_epi32(c,e);
            __m256i u0=_mm256_unpacklo_epi64(t0,t1),u1=_mm256_unpackhi_epi64(t0,t1);
            __m256i u2=_mm256_unpacklo_epi64(t2,t3),u3=_mm256_unpackhi_epi64(t2,t3);
            st(d,_mm256_permute2x128_si256(u0,u1,0x20));
            st(d+16,_mm256_permute2x128_si256(u2,u3,0x20));
            st(d+32,_mm256_permute2x128_si256(u0,u1,0x31));
            st(d+48,_mm256_permute2x128_si256(u2,u3,0x31));d+=64;
        }
    } else {
        const int transformed=(((s-raw_basis_input)&32) && ((s-raw_basis_input)&(32*4096)))?1:0;
        for(int k=0;k<n;k+=2) for(int j=0;j<n;) {
            int w=32;
            U *v=d+j*n+k*w;
            for(int t=0;t<w;t+=16) {
                if(t+16<=w) {
                    __m256i x=raw_basis32(s+k*stride+j+t,transformed);
                    __m256i y=raw_basis32(s+(k+1)*stride+j+t,transformed);
                    st(v,_mm256_unpacklo_epi16(x,y));
                    st(v+16,_mm256_unpackhi_epi16(x,y));v+=32;
                } else {
                    __m128i x=_mm_load_si128((const __m128i*)(s+k*stride+j+t));
                    __m128i y=_mm_load_si128((const __m128i*)(s+(k+1)*stride+j+t));
                    _mm_store_si128((__m128i*)v,_mm_unpacklo_epi16(x,y));
                    _mm_store_si128((__m128i*)(v+8),_mm_unpackhi_epi16(x,y));v+=16;
                }
            }
            j+=w;
        }
    }
}

static void unpack(U *d, const U *s, int n, int stride) {
    if (n > BASE) {
        int h = n/2, q=h*h+(h/BASE)*(h/BASE)*TILE_PAD;
        unpack(d,s,h,stride);
        unpack(d+h,s+q,h,stride);
        unpack(d+h*stride,s+2*q,h,stride);
        unpack(d+h*stride+h,s+3*q,h,stride);
    } else {
        for (int i=0;i<n;++i) {
            U *dp = d + (size_t)i*stride; const U *sp = s + (size_t)i*n;
            int k=0;
            for (;k+32<=n;k+=32) {
                _mm256_stream_si256((__m256i*)(dp+k),    _mm256_load_si256((const __m256i*)(sp+k)));
                _mm256_stream_si256((__m256i*)(dp+k+16), _mm256_load_si256((const __m256i*)(sp+k+16)));
            }
            for (;k<n;k+=16) _mm256_storeu_si256((__m256i*)(dp+k), _mm256_loadu_si256((const __m256i*)(sp+k)));
        }
    }
}

// ===== s4bj_ : 叶尾改 blend 后,每个 16 字组内被 sigma 置换,decode 前先复原 =====
// sigma   = [0,4,1,5,2,6,3,7 | 8,12,9,13,10,14,11,15]   (new[j] = old[sigma(j)])
// sigma^-1= [0,2,4,6,1,3,5,7 | 8,10,12,14,9,11,13,15]   (old[i] = new[sigma^-1(i)])
alignas(32) static const unsigned char s4bj_si[32] = {
 0,1,4,5,8,9,12,13,2,3,6,7,10,11,14,15, 0,1,4,5,8,9,12,13,2,3,6,7,10,11,14,15};
static inline __m256i s4bj_fx(__m256i v) {
    return _mm256_shuffle_epi8(v, _mm256_load_si256((const __m256i *)s4bj_si));
}
alignas(32) unsigned short s4aj_m16[16] = {0xFFFF,0,0xFFFF,0,0xFFFF,0,0xFFFF,0,0xFFFF,0,0xFFFF,0,0xFFFF,0,0xFFFF,0};
alignas(32) unsigned char s4ak_sh16[32] = {0,1,4,5,8,9,12,13, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0,1,4,5,8,9,12,13, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80};
// One explicit panel/row loop keeps exactly one copy of the large kernel.
template<int Mode>
static inline void native2x32_cache3(const U *a,const U *b,U *c) {
    const U *a_final=a+1024;
    intptr_t astep=8; // byte steps8,248 alternate within and across4-row A packs
    asm volatile(
        "3:\n\t"
        "vmovdqa 0(%[b]), %%ymm8\n\t"
        "vmovdqa 32(%[b]), %%ymm9\n\t"
        "vmovdqa 64(%[b]), %%ymm10\n\t"
        "vpbroadcastd 0(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm0\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm1\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm2\n\t"
        "vpmaddwd 96(%[b]), %%ymm11, %%ymm3\n\t"
        "vpbroadcastd 4(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm4\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm5\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm6\n\t"
        "vpmaddwd 96(%[b]), %%ymm11, %%ymm7\n\t"
        "vmovdqa 128(%[b]), %%ymm8\n\t"
        "vmovdqa 160(%[b]), %%ymm9\n\t"
        "vmovdqa 192(%[b]), %%ymm10\n\t"
        "vpbroadcastd 16(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 224(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 20(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 224(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 256(%[b]), %%ymm8\n\t"
        "vmovdqa 288(%[b]), %%ymm9\n\t"
        "vmovdqa 320(%[b]), %%ymm10\n\t"
        "vpbroadcastd 32(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 352(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 36(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 352(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 384(%[b]), %%ymm8\n\t"
        "vmovdqa 416(%[b]), %%ymm9\n\t"
        "vmovdqa 448(%[b]), %%ymm10\n\t"
        "vpbroadcastd 48(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 480(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 52(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 480(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 512(%[b]), %%ymm8\n\t"
        "vmovdqa 544(%[b]), %%ymm9\n\t"
        "vmovdqa 576(%[b]), %%ymm10\n\t"
        "vpbroadcastd 64(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 608(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 68(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 608(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 640(%[b]), %%ymm8\n\t"
        "vmovdqa 672(%[b]), %%ymm9\n\t"
        "vmovdqa 704(%[b]), %%ymm10\n\t"
        "vpbroadcastd 80(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 736(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 84(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 736(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 768(%[b]), %%ymm8\n\t"
        "vmovdqa 800(%[b]), %%ymm9\n\t"
        "vmovdqa 832(%[b]), %%ymm10\n\t"
        "vpbroadcastd 96(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 864(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 100(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 864(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 896(%[b]), %%ymm8\n\t"
        "vmovdqa 928(%[b]), %%ymm9\n\t"
        "vmovdqa 960(%[b]), %%ymm10\n\t"
        "vpbroadcastd 112(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 992(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 116(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 992(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 1024(%[b]), %%ymm8\n\t"
        "vmovdqa 1056(%[b]), %%ymm9\n\t"
        "vmovdqa 1088(%[b]), %%ymm10\n\t"
        "vpbroadcastd 128(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 1120(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 132(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 1120(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 1152(%[b]), %%ymm8\n\t"
        "vmovdqa 1184(%[b]), %%ymm9\n\t"
        "vmovdqa 1216(%[b]), %%ymm10\n\t"
        "vpbroadcastd 144(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 1248(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 148(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 1248(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 1280(%[b]), %%ymm8\n\t"
        "vmovdqa 1312(%[b]), %%ymm9\n\t"
        "vmovdqa 1344(%[b]), %%ymm10\n\t"
        "vpbroadcastd 160(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 1376(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 164(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 1376(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 1408(%[b]), %%ymm8\n\t"
        "vmovdqa 1440(%[b]), %%ymm9\n\t"
        "vmovdqa 1472(%[b]), %%ymm10\n\t"
        "vpbroadcastd 176(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 1504(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 180(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 1504(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 1536(%[b]), %%ymm8\n\t"
        "vmovdqa 1568(%[b]), %%ymm9\n\t"
        "vmovdqa 1600(%[b]), %%ymm10\n\t"
        "vpbroadcastd 192(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 1632(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 196(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 1632(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 1664(%[b]), %%ymm8\n\t"
        "vmovdqa 1696(%[b]), %%ymm9\n\t"
        "vmovdqa 1728(%[b]), %%ymm10\n\t"
        "vpbroadcastd 208(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 1760(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 212(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 1760(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 1792(%[b]), %%ymm8\n\t"
        "vmovdqa 1824(%[b]), %%ymm9\n\t"
        "vmovdqa 1856(%[b]), %%ymm10\n\t"
        "vpbroadcastd 224(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 1888(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 228(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 1888(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vmovdqa 1920(%[b]), %%ymm8\n\t"
        "vmovdqa 1952(%[b]), %%ymm9\n\t"
        "vmovdqa 1984(%[b]), %%ymm10\n\t"
        "vpbroadcastd 240(%[a]), %%ymm11\n\t"
        "vpmaddwd %%ymm8, %%ymm11, %%ymm12\n\t"
        "vpmaddwd %%ymm9, %%ymm11, %%ymm13\n\t"
        "vpmaddwd %%ymm10, %%ymm11, %%ymm14\n\t"
        "vpmaddwd 2016(%[b]), %%ymm11, %%ymm11\n\t"
        "vpbroadcastd 244(%[a]), %%ymm15\n\t"
        "vpmaddwd %%ymm8, %%ymm15, %%ymm8\n\t"
        "vpmaddwd %%ymm9, %%ymm15, %%ymm9\n\t"
        "vpmaddwd %%ymm10, %%ymm15, %%ymm10\n\t"
        "vpmaddwd 2016(%[b]), %%ymm15, %%ymm15\n\t"
        "vpaddd %%ymm12, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm11, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm8, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm9, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm10, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm15, %%ymm7, %%ymm7\n\t"
        "vpslld $16, %%ymm1, %%ymm1\n\t"
        "vpblendw $0xAA, %%ymm1, %%ymm0, %%ymm0\n\t"
        ".if %c[mode] == 1\n\t"
        "vpaddw 0(%[c]), %%ymm0, %%ymm0\n\t"
        ".endif\n\t"
        "vmovdqu %%ymm0, 0(%[c])\n\t"
        "vpslld $16, %%ymm3, %%ymm3\n\t"
        "vpblendw $0xAA, %%ymm3, %%ymm2, %%ymm2\n\t"
        ".if %c[mode] == 1\n\t"
        "vpaddw 32(%[c]), %%ymm2, %%ymm2\n\t"
        ".endif\n\t"
        "vmovdqu %%ymm2, 32(%[c])\n\t"
        "vpslld $16, %%ymm5, %%ymm5\n\t"
        "vpblendw $0xAA, %%ymm5, %%ymm4, %%ymm4\n\t"
        ".if %c[mode] == 1\n\t"
        "vpaddw 64(%[c]), %%ymm4, %%ymm4\n\t"
        ".endif\n\t"
        "vmovdqu %%ymm4, 64(%[c])\n\t"
        "vpslld $16, %%ymm7, %%ymm7\n\t"
        "vpblendw $0xAA, %%ymm7, %%ymm6, %%ymm6\n\t"
        ".if %c[mode] == 1\n\t"
        "vpaddw 96(%[c]), %%ymm6, %%ymm6\n\t"
        ".endif\n\t"
        "vmovdqu %%ymm6, 96(%[c])\n\t"
        "add %[astep], %[a]\n\t"
        "xor $240, %[astep]\n\t"
        "add $128, %[c]\n\t"
        "cmp %[a_final], %[a]\n\t"
        "jb 3b\n\t"
        : [a] "+&r"(a), [c] "+&r"(c), [astep] "+&r"(astep)
        : [b] "r"(b), [a_final] "r"(a_final), [mode] "i"(Mode)
        : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15");
}
static void base(const U *a,const U *b,U *c,int n) {
    native2x32_cache3<0>(a,b,c);
}
// Only one additional hot body: M1, M3 and the negated-M7 update all add.
static __attribute__((noinline)) void leaf_add(const U*a,const U*b,U*c){
 native2x32_cache3<1>(a,b,c);
}
static inline void emit_native(U *dst,const U *s,int stride) {
    for(int row=0;row<4;++row) {
        U *d=dst+(size_t)row*stride;
        _mm256_stream_si256((__m256i*)(d+0),s4bj_fx(ld(s+32*row)));
        _mm256_stream_si256((__m256i*)(d+16),s4bj_fx(ld(s+32*row+16)));
    }
}

template<bool Sub>
static inline void combine(U *d,const U *a,const U *b,int len) {
    #pragma GCC unroll 1
    for(int chunk=0;chunk<len;chunk+=1024+TILE_PAD) {
        const U *end=a+1024;
        if constexpr(Sub) {
            asm volatile(
        "1:\n\t"
        "vmovdqa 0(%[a]), %%ymm0\n\t"
        "vmovdqa 32(%[a]), %%ymm1\n\t"
        "vmovdqa 64(%[a]), %%ymm2\n\t"
        "vmovdqa 96(%[a]), %%ymm3\n\t"
        "vpsubw 0(%[b]), %%ymm0, %%ymm0\n\t"
        "vpsubw 32(%[b]), %%ymm1, %%ymm1\n\t"
        "vpsubw 64(%[b]), %%ymm2, %%ymm2\n\t"
        "vpsubw 96(%[b]), %%ymm3, %%ymm3\n\t"
        "vmovdqa %%ymm0, 0(%[d])\n\t"
        "vmovdqa %%ymm1, 32(%[d])\n\t"
        "vmovdqa %%ymm2, 64(%[d])\n\t"
        "vmovdqa %%ymm3, 96(%[d])\n\t"
        "add $128, %[a]\n\t"
        "add $128, %[b]\n\t"
        "add $128, %[d]\n\t"
        "cmp %[end], %[a]\n\t"
        "jb 1b\n\t"
        : [a] "+&r"(a), [b] "+&r"(b), [d] "+&r"(d)
        : [end] "r"(end)
        : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3");
        } else {
            asm volatile(
        "1:\n\t"
        "vmovdqa 0(%[a]), %%ymm0\n\t"
        "vmovdqa 32(%[a]), %%ymm1\n\t"
        "vmovdqa 64(%[a]), %%ymm2\n\t"
        "vmovdqa 96(%[a]), %%ymm3\n\t"
        "vpaddw 0(%[b]), %%ymm0, %%ymm0\n\t"
        "vpaddw 32(%[b]), %%ymm1, %%ymm1\n\t"
        "vpaddw 64(%[b]), %%ymm2, %%ymm2\n\t"
        "vpaddw 96(%[b]), %%ymm3, %%ymm3\n\t"
        "vmovdqa %%ymm0, 0(%[d])\n\t"
        "vmovdqa %%ymm1, 32(%[d])\n\t"
        "vmovdqa %%ymm2, 64(%[d])\n\t"
        "vmovdqa %%ymm3, 96(%[d])\n\t"
        "add $128, %[a]\n\t"
        "add $128, %[b]\n\t"
        "add $128, %[d]\n\t"
        "cmp %[end], %[a]\n\t"
        "jb 1b\n\t"
        : [a] "+&r"(a), [b] "+&r"(b), [d] "+&r"(d)
        : [end] "r"(end)
        : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3");
        }
        a+=TILE_PAD;b+=TILE_PAD;d+=TILE_PAD;
    }
}

template<bool Sub,int Delta>
static inline void combine_displaced(U *d,const U *a,int len) {
 #pragma GCC unroll 1
 for(int chunk=0;chunk<len;chunk+=1024+TILE_PAD) {
 const U *end=a+1024;
 if constexpr(Sub) {
 asm volatile("1:\n\t"
 "vmovdqa 0(%[a]), %%ymm0\n\t"
 "vmovdqa 32(%[a]), %%ymm1\n\t"
 "vmovdqa 64(%[a]), %%ymm2\n\t"
 "vmovdqa 96(%[a]), %%ymm3\n\t"
 "vpsubw %c[delta]+0(%[a]), %%ymm0, %%ymm0\n\t"
 "vpsubw %c[delta]+32(%[a]), %%ymm1, %%ymm1\n\t"
 "vpsubw %c[delta]+64(%[a]), %%ymm2, %%ymm2\n\t"
 "vpsubw %c[delta]+96(%[a]), %%ymm3, %%ymm3\n\t"
 "vmovdqa %%ymm0, 0(%[d])\n\t"
 "vmovdqa %%ymm1, 32(%[d])\n\t"
 "vmovdqa %%ymm2, 64(%[d])\n\t"
 "vmovdqa %%ymm3, 96(%[d])\n\t"
 "add $128, %[a]\n\t"
 "add $128, %[d]\n\t"
 "cmp %[end], %[a]\n\t"
 "jb 1b\n\t"
 : [a] "+&r"(a), [d] "+&r"(d)
 : [end] "r"(end), [delta] "i"(2*Delta)
 : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3");
 } else {
 asm volatile("1:\n\t"
 "vmovdqa 0(%[a]), %%ymm0\n\t"
 "vmovdqa 32(%[a]), %%ymm1\n\t"
 "vmovdqa 64(%[a]), %%ymm2\n\t"
 "vmovdqa 96(%[a]), %%ymm3\n\t"
 "vpaddw %c[delta]+0(%[a]), %%ymm0, %%ymm0\n\t"
 "vpaddw %c[delta]+32(%[a]), %%ymm1, %%ymm1\n\t"
 "vpaddw %c[delta]+64(%[a]), %%ymm2, %%ymm2\n\t"
 "vpaddw %c[delta]+96(%[a]), %%ymm3, %%ymm3\n\t"
 "vmovdqa %%ymm0, 0(%[d])\n\t"
 "vmovdqa %%ymm1, 32(%[d])\n\t"
 "vmovdqa %%ymm2, 64(%[d])\n\t"
 "vmovdqa %%ymm3, 96(%[d])\n\t"
 "add $128, %[a]\n\t"
 "add $128, %[d]\n\t"
 "cmp %[end], %[a]\n\t"
 "jb 1b\n\t"
 : [a] "+&r"(a), [d] "+&r"(d)
 : [end] "r"(end), [delta] "i"(2*Delta)
 : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3");
 }
 a+=TILE_PAD;d+=TILE_PAD;
 }
}

// pdoom frontier6: the output is its own first operand, so only two
// advancing addresses are necessary. N64 calls touch a single valid leaf.
template<bool Sub>
static inline void combine_inplace(U *d,const U *b,int len) {
 #pragma GCC unroll 1
 for(int chunk=0;chunk<len;chunk+=1024+TILE_PAD) {
 const U *end=d+1024;
 if constexpr(Sub) {
 asm volatile("1:\n\t"
 "vmovdqa 0(%[d]), %%ymm0\n\t"
 "vmovdqa 32(%[d]), %%ymm1\n\t"
 "vmovdqa 64(%[d]), %%ymm2\n\t"
 "vmovdqa 96(%[d]), %%ymm3\n\t"
 "vpsubw 0(%[b]), %%ymm0, %%ymm0\n\t"
 "vpsubw 32(%[b]), %%ymm1, %%ymm1\n\t"
 "vpsubw 64(%[b]), %%ymm2, %%ymm2\n\t"
 "vpsubw 96(%[b]), %%ymm3, %%ymm3\n\t"
 "vmovdqa %%ymm0, 0(%[d])\n\t"
 "vmovdqa %%ymm1, 32(%[d])\n\t"
 "vmovdqa %%ymm2, 64(%[d])\n\t"
 "vmovdqa %%ymm3, 96(%[d])\n\t"
 "add $128, %[d]\n\t"
 "add $128, %[b]\n\t"
 "cmp %[end], %[d]\n\t"
 "jb 1b\n\t"
 : [d] "+&r"(d), [b] "+&r"(b)
 : [end] "r"(end)
 : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3");
 } else {
 asm volatile("1:\n\t"
 "vmovdqa 0(%[d]), %%ymm0\n\t"
 "vmovdqa 32(%[d]), %%ymm1\n\t"
 "vmovdqa 64(%[d]), %%ymm2\n\t"
 "vmovdqa 96(%[d]), %%ymm3\n\t"
 "vpaddw 0(%[b]), %%ymm0, %%ymm0\n\t"
 "vpaddw 32(%[b]), %%ymm1, %%ymm1\n\t"
 "vpaddw 64(%[b]), %%ymm2, %%ymm2\n\t"
 "vpaddw 96(%[b]), %%ymm3, %%ymm3\n\t"
 "vmovdqa %%ymm0, 0(%[d])\n\t"
 "vmovdqa %%ymm1, 32(%[d])\n\t"
 "vmovdqa %%ymm2, 64(%[d])\n\t"
 "vmovdqa %%ymm3, 96(%[d])\n\t"
 "add $128, %[d]\n\t"
 "add $128, %[b]\n\t"
 "cmp %[end], %[d]\n\t"
 "jb 1b\n\t"
 : [d] "+&r"(d), [b] "+&r"(b)
 : [end] "r"(end)
 : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3");
 }
 d+=TILE_PAD;b+=TILE_PAD;
 }
}

// pdoom frontier6: the output is its own first operand, so only two
// advancing addresses are necessary. N64 calls touch a single valid leaf.

static inline void combine_reverse_inplace(U *d,const U *b,int len) {
 #pragma GCC unroll 1
 for(int chunk=0;chunk<len;chunk+=1024+TILE_PAD) {
 const U *end=d+1024;
 asm volatile("1:\n\t"
 "vmovdqa 0(%[b]), %%ymm0\n\t"
 "vmovdqa 32(%[b]), %%ymm1\n\t"
 "vmovdqa 64(%[b]), %%ymm2\n\t"
 "vmovdqa 96(%[b]), %%ymm3\n\t"
 "vpsubw 0(%[d]), %%ymm0, %%ymm0\n\t"
 "vpsubw 32(%[d]), %%ymm1, %%ymm1\n\t"
 "vpsubw 64(%[d]), %%ymm2, %%ymm2\n\t"
 "vpsubw 96(%[d]), %%ymm3, %%ymm3\n\t"
 "vmovdqa %%ymm0, 0(%[d])\n\t"
 "vmovdqa %%ymm1, 32(%[d])\n\t"
 "vmovdqa %%ymm2, 64(%[d])\n\t"
 "vmovdqa %%ymm3, 96(%[d])\n\t"
 "add $128, %[d]\n\t"
 "add $128, %[b]\n\t"
 "cmp %[end], %[d]\n\t"
 "jb 1b\n\t"
 : [d] "+&r"(d), [b] "+&r"(b)
 : [end] "r"(end)
 : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3");
 d+=TILE_PAD;b+=TILE_PAD;
 }
}

// At the root, the three completed packed quadrants can be sent straight
// to their final row-major destinations rather than materialized in pc.
template<int N>
static __attribute__((noinline)) void combine3_unpack(
    U *d12,U *d21,U *d22,
    const U *p6,const U *p7,const U *p5,
    const U *p1,const U *p4,const U *p3,int stride) {
    if constexpr (N > BASE) {
        constexpr int h=N/2,q=h*h+(h/BASE)*(h/BASE)*TILE_PAD;
        combine3_unpack<h>(d12,d21,d22,p6,p7,p5,p1,p4,p3,stride);
        combine3_unpack<h>(d12+h,d21+h,d22+h,p6+q,p7+q,p5+q,p1+q,p4+q,p3+q,stride);
        combine3_unpack<h>(d12+h*stride,d21+h*stride,d22+h*stride,
                           p6+2*q,p7+2*q,p5+2*q,p1+2*q,p4+2*q,p3+2*q,stride);
        combine3_unpack<h>(d12+h*stride+h,d21+h*stride+h,d22+h*stride+h,
                           p6+3*q,p7+3*q,p5+3*q,p1+3*q,p4+3*q,p3+3*q,stride);
    } else {
        alignas(32) U temp[3*128];
        for(int block=0;block<1024;block=block+128) {
            for(int v=0;v<128;v+=16) {
                int idx=block+v;
                __m256i u2=_mm256_add_epi16(ld(p1+idx),ld(p6+idx));
                __m256i u3=_mm256_add_epi16(u2,ld(p7+idx));
                __m256i v5=ld(p5+idx);
                st(temp+v,_mm256_add_epi16(_mm256_add_epi16(u2,v5),ld(p3+idx)));
                st(temp+128+v,_mm256_sub_epi16(u3,ld(p4+idx)));
                st(temp+256+v,_mm256_add_epi16(u3,v5));
            }
            size_t off=(size_t)(block/32)*stride;
            emit_native(d12+off,temp,stride);
            emit_native(d21+off,temp+128,stride);
            emit_native(d22+off,temp+256,stride);
        }
    }
}

// Add the surviving P1 into the root C11 product while mapping its packed
// quadrant layout to the final row-major C11 cells.
template<int N>
static __attribute__((noinline)) void unpack_add(U *d,const U *p2,const U *p1,int stride) {
    if constexpr(N>BASE) {
        constexpr int h=N/2,q=h*h+(h/BASE)*(h/BASE)*TILE_PAD;
        unpack_add<h>(d,p2,p1,stride);
        unpack_add<h>(d+h,p2+q,p1+q,stride);
        unpack_add<h>(d+h*stride,p2+2*q,p1+2*q,stride);
        unpack_add<h>(d+h*stride+h,p2+3*q,p1+3*q,stride);
    } else {
        alignas(32) U temp[128];
        for(int block=0;block<1024;block+=128) {
            for(int v=0;v<128;v+=16)
                st(temp+v,_mm256_add_epi16(ld(p2+block+v),ld(p1+block+v)));
            emit_native(d+(size_t)(block/32)*stride,temp,stride);
        }
    }
}

// Strassen-Winograd: seven products, fifteen additions, two temporaries.
// All operations are in Z/(2^16); truncation never changes the answer.

template<int N>
static __attribute__((noinline)) void root_fuse(
    U *d11,U *d12,U *d21,U *d22,
    const U *p1,const U *p2,const U *p3,const U *p4,const U *p5,const U *p6,const U *p7,int stride) {
    if constexpr(N==128) {
        constexpr int q=BASE*BASE+TILE_PAD;
        root_fuse<64>(d11,d12,d21,d22,p1,p2,p3,p4,p5,p6,p7,stride);
        alignas(32) U keep[4*512], cur[4*512];
        U *dest[4]={d11,d12,d21,d22};
        for(int block=0;block<1024;block+=128) {
            auto make_inner=[&](U *tmp,int group) {
                for(int child=0;child<4;child++) {
                    for(int v=0;v<128;v+=16) {
                        int idx=(4*group+child)*q+block+v;
                        __m256i v1=ld(p1+idx),v5=ld(p5+idx);
                        __m256i u2=_mm256_add_epi16(v1,ld(p6+idx));
                        __m256i u3=_mm256_add_epi16(u2,ld(p7+idx));
                        U *t=tmp+child*512;
                        st(t+v,_mm256_add_epi16(v1,ld(p2+idx)));
                        st(t+128+v,_mm256_add_epi16(_mm256_add_epi16(u2,v5),ld(p3+idx)));
                        st(t+256+v,_mm256_sub_epi16(u3,ld(p4+idx)));
                        st(t+384+v,_mm256_add_epi16(u3,v5));
                    }
                }
                for(int v=0;v<512;v+=16) {
                    __m256i c22=ld(tmp+3*512+v);
                    st(tmp+1*512+v,_mm256_sub_epi16(ld(tmp+1*512+v),c22));
                    st(tmp+2*512+v,_mm256_sub_epi16(c22,ld(tmp+2*512+v)));
                }
            };
            size_t off=(size_t)(block/32)*stride;
            make_inner(keep,3);
            for(int child=0;child<4;child++) {
                int row=64+((child>>1)&1)*32,col=64+(child&1)*32;
                for(int r=0;r<4;r++)emit_native(dest[r]+off+row*stride+col,keep+child*512+r*128,stride);
            }
            for(int group=1;group<=2;group++) {
                make_inner(cur,group);
                for(int child=0;child<4;child++) {
                    int row=((group>>1)&1)*64+((child>>1)&1)*32;
                    int col=(group&1)*64+(child&1)*32;
                    for(int r=0;r<4;r++)for(int rr=0;rr<4;rr++) {
                        U *d=dest[r]+off+(row+rr)*stride+col;
                        const U *x=cur+child*512+r*128+rr*32;
                        const U *y=keep+child*512+r*128+rr*32;
                        __m256i v0,v1;
                        if(group==1) {
                            v0=_mm256_sub_epi16(ld(x),ld(y));
                            v1=_mm256_sub_epi16(ld(x+16),ld(y+16));
                        } else {
                            v0=_mm256_sub_epi16(ld(y),ld(x));
                            v1=_mm256_sub_epi16(ld(y+16),ld(x+16));
                        }
                        _mm256_stream_si256((__m256i*)d,s4bj_fx(v0));
                        _mm256_stream_si256((__m256i*)(d+16),s4bj_fx(v1));
                    }
                }
            }
        }
    } else if constexpr(N==64) {
        constexpr int q=BASE*BASE+TILE_PAD;
        root_fuse<32>(d11,d12,d21,d22,p1,p2,p3,p4,p5,p6,p7,stride);
        alignas(32) U tmp[3*4*128];
        U *dest[4]={d11,d12,d21,d22};
        for(int block=0;block<1024;block+=128) {
            for(int child=1;child<=3;child++) {
                for(int v=0;v<128;v+=16) {
                    int idx=child*q+block+v;
                    __m256i v1=ld(p1+idx),v5=ld(p5+idx);
                    __m256i u2=_mm256_add_epi16(v1,ld(p6+idx));
                    __m256i u3=_mm256_add_epi16(u2,ld(p7+idx));
                    U *t=tmp+(child-1)*512;
                    st(t+v,_mm256_add_epi16(v1,ld(p2+idx)));
                    st(t+128+v,_mm256_add_epi16(_mm256_add_epi16(u2,v5),ld(p3+idx)));
                    st(t+256+v,_mm256_sub_epi16(u3,ld(p4+idx)));
                    st(t+384+v,_mm256_add_epi16(u3,v5));
                }
            }
            for(int v=0;v<512;v+=16) {
                __m256i c22=ld(tmp+1024+v);
                st(tmp+v,_mm256_sub_epi16(ld(tmp+v),c22));
                st(tmp+512+v,_mm256_sub_epi16(c22,ld(tmp+512+v)));
            }
            size_t off=(size_t)(block/32)*stride;
            for(int r=0;r<4;r++) {
                emit_native(dest[r]+off+32,tmp+r*128,stride);
                emit_native(dest[r]+off+32*stride,tmp+512+r*128,stride);
                emit_native(dest[r]+off+32*stride+32,tmp+1024+r*128,stride);
            }
        }
    } else if constexpr (N > BASE) {
        constexpr int h=N/2,q=h*h+(h/BASE)*(h/BASE)*TILE_PAD;
        root_fuse<h>(d11,d12,d21,d22,p1,p2,p3,p4,p5,p6,p7,stride);
        root_fuse<h>(d11+h,d12+h,d21+h,d22+h,p1+q,p2+q,p3+q,p4+q,p5+q,p6+q,p7+q,stride);
        root_fuse<h>(d11+h*stride,d12+h*stride,d21+h*stride,d22+h*stride,
                     p1+2*q,p2+2*q,p3+2*q,p4+2*q,p5+2*q,p6+2*q,p7+2*q,stride);
        root_fuse<h>(d11+h*stride+h,d12+h*stride+h,d21+h*stride+h,d22+h*stride+h,
                     p1+3*q,p2+3*q,p3+3*q,p4+3*q,p5+3*q,p6+3*q,p7+3*q,stride);
    } else {
        alignas(32) U temp[4*128];
        for(int block=0;block<1024;block+=128) {
            for(int v=0;v<128;v+=16) {
                int idx=block+v;
                __m256i u2=_mm256_add_epi16(ld(p1+idx),ld(p6+idx));
                __m256i u3=_mm256_add_epi16(u2,ld(p7+idx));
                __m256i v5=ld(p5+idx);
                st(temp+v,_mm256_add_epi16(_mm256_add_epi16(u2,v5),ld(p3+idx)));
                st(temp+128+v,_mm256_sub_epi16(u3,ld(p4+idx)));
                st(temp+256+v,_mm256_add_epi16(u3,v5));
                st(temp+384+v,_mm256_add_epi16(ld(p2+idx),ld(p1+idx)));
            }
            size_t off=(size_t)(block/32)*stride;
            emit_native(d12+off,temp,stride);
            emit_native(d21+off,temp+128,stride);
            emit_native(d22+off,temp+256,stride);
            emit_native(d11+off,temp+384,stride);
        }
    }
}

template<int N>
static __attribute__((noinline)) void mul(const U *a,const U *b,U *c,U *work) {
    if constexpr (N<=BASE) {
        base(a,b,c,N);
    } else if constexpr (N<=ALTMAX) {

  constexpr int h=N/2,q=h*h+(h/BASE)*(h/BASE)*TILE_PAD;
  const U *a11=a,*a12=a+q,*a21=a+2*q,*a22=a+3*q;
  const U *b11=b,*b12=b+q,*b21=b+2*q,*b22=b+3*q;
  U *c11=c,*c12=c+q,*c21=c+2*q,*c22=c+3*q;
  U *x=work+0,*y=work+2*q+704,*next=work+4*q+640;
  mul<h>(a12,b21,c11,next);                 // m2
  mul<h>(a22,b22,c22,next);                 // m4
  combine_displaced<false,q>(x,a21,q);
  combine_displaced<false,q>(y,b21,q);
  mul<h>(x,y,c12,next);                     // m5
  combine_displaced<true,-2*q>(x,a22,q);
  combine_displaced<true,-2*q>(y,b22,q);
  mul<h>(x,y,c21,next);                     // m6
  for(int chunk=0;chunk<q;chunk+=1024+TILE_PAD)
   _Pragma("GCC unroll 4")
   for(int i=chunk;i<chunk+1024;i+=16)
   st(c22+i,_mm256_sub_epi16(_mm256_add_epi16(ld(c12+i),ld(c21+i)),_mm256_add_epi16(ld(c11+i),ld(c22+i))));
  if constexpr(N==64) {
   leaf_add(a11,b11,c11);                  // m1 directly accumulates
   combine_displaced<true,-3*q>(y,b22,q);
   leaf_add(a21,y,c21);                    // m3 directly accumulates
   combine_displaced<true,3*q>(x,a11,q);   // negate the M7 A input
   leaf_add(x,b12,c12);                    // c12+=(-oldM7)
  } else {
  mul<h>(a11,b11,x,next);                   // m1
  combine_inplace<false>(c11,x,q);
  combine_displaced<true,-3*q>(y,b22,q);
  mul<h>(a21,y,x,next);                     // m3
  combine_inplace<false>(c21,x,q);
  combine_displaced<true,-3*q>(x,a22,q);
  mul<h>(x,b12,y,next);                     // m7
  combine_inplace<true>(c12,y,q);
  }
    } else {
    constexpr int h=N/2,q=h*h+(h/BASE)*(h/BASE)*TILE_PAD;
    const U *a11=a,*a12=a+q,*a21=a+2*q,*a22=a+3*q;
    const U *b11=b,*b12=b+q,*b21=b+2*q,*b22=b+3*q;
    U *c11=c,*c12=c+q,*c21=c+2*q,*c22=c+3*q;
    U *x=work+192,*y=work+q+512,*next=work+q+q+512;
    combine_displaced<true,-2*q>(y,b22,q);
    combine_displaced<true,2*q>(x,a11,q);
    mul<h>(x,y,c21,next);                       // P7
    combine_displaced<false,q>(x,a21,q);
    combine_displaced<true,-q>(y,b12,q);
    mul<h>(x,y,c22,next);                       // P5
    combine_inplace<true>(x,a11,q);
    combine_reverse_inplace(y,b22,q);
    mul<h>(x,y,c12,next);                       // P6
    combine_reverse_inplace(x,a12,q);
    mul<h>(x,b22,c11,next);                     // P3
    combine_inplace<true>(y,b21,q);
    mul<h>(a22,y,x,next);                       // P4
    mul<h>(a11,b11,y,next);                     // P1
    if constexpr (N == 4096) {
        combine3_unpack<2048>(final_out+2048,
            final_out+(size_t)2048*4096,
            final_out+(size_t)2048*4096+2048,
            c12,c21,c22,y,x,c11,4096);
    } else {
        for(int chunk=0;chunk<q;chunk+=1024+TILE_PAD) for(int i=chunk;i<chunk+1024;i+=16) {
            __m256i u2=_mm256_add_epi16(ld(y+i),ld(c12+i));
            __m256i u3=_mm256_add_epi16(u2,ld(c21+i));
            __m256i p5=ld(c22+i);
            st(c12+i,_mm256_add_epi16(_mm256_add_epi16(u2,p5),ld(c11+i)));
            st(c21+i,_mm256_sub_epi16(u3,ld(x+i)));
            st(c22+i,_mm256_add_epi16(u3,p5));
        }
    }
    mul<h>(a12,b21,c11,next);                   // P2
    if constexpr (N == 4096) unpack_add<2048>(final_out,c11,y,4096);
    else combine_inplace<false>(c11,y,q);
    }
}


static constexpr int RQ=2048*2048+(2048/BASE)*(2048/BASE)*TILE_PAD,RS=RQ+ROOT_PAD;
alignas(4096) static U root_mem[15*RS+4096];
alignas(4096) static U root_tile[4*(64*64+(64/BASE)*(64/BASE)*TILE_PAD)];
static constexpr int HQ=64*64+(64/BASE)*(64/BASE)*TILE_PAD;
alignas(4096) static U high_left[4*HQ],high_right[4*HQ];

// staged variant: the source tile lives in a dense 64x64 window (stride = ST), so the
// "32 rows up" neighbour of the BR sub-leaf is p-32*ST -- inside the same 64x64 block.
template<int ST>
static inline __m256i raw_low32_st(const U *p, bool transformed) {
    __m256i v = _mm256_loadu_si256((const __m256i *)p);
    if (transformed) v = _mm256_add_epi16(v, _mm256_sub_epi16(
        _mm256_loadu_si256((const __m256i *)(p - 32 * ST)),
        _mm256_loadu_si256((const __m256i *)(p - 32))));
    return v;
}
// ======================= 32x32 leaf, STAGED source (dense 64x64 window) =======================
template<bool Right, bool TR> static __attribute__((noinline)) void pack_leaf32_st(U *d, const U *s) {
    if (!Right) {
        for (int i = 0; i < 32; i += 4) for (int k = 0; k < 32; k += 16) {
            __m256i a = raw_low32_st<64>(s + i * 64 + k, TR), b = raw_low32_st<64>(s + (i + 1) * 64 + k, TR);
            __m256i c = raw_low32_st<64>(s + (i + 2) * 64 + k, TR), e = raw_low32_st<64>(s + (i + 3) * 64 + k, TR);
            __m256i t0 = _mm256_unpacklo_epi32(a, b), t1 = _mm256_unpacklo_epi32(c, e);
            __m256i t2 = _mm256_unpackhi_epi32(a, b), t3 = _mm256_unpackhi_epi32(c, e);
            __m256i u0 = _mm256_unpacklo_epi64(t0, t1), u1 = _mm256_unpackhi_epi64(t0, t1);
            __m256i u2 = _mm256_unpacklo_epi64(t2, t3), u3 = _mm256_unpackhi_epi64(t2, t3);
            _mm256_store_si256((__m256i *)d, _mm256_permute2x128_si256(u0, u1, 0x20));
            _mm256_store_si256((__m256i *)(d + 16), _mm256_permute2x128_si256(u2, u3, 0x20));
            _mm256_store_si256((__m256i *)(d + 32), _mm256_permute2x128_si256(u0, u1, 0x31));
            _mm256_store_si256((__m256i *)(d + 48), _mm256_permute2x128_si256(u2, u3, 0x31));
            d += 64;
        }
    } else {
        for (int k = 0; k < 32; k += 2) for (int j = 0; j < 32;) {
            int w = 32;
            U *v = d + j * 32 + k * w;
            for (int t = 0; t < w; t += 16) {
                __m256i x = raw_low32_st<64>(s + k * 64 + j + t, TR);
                __m256i y = raw_low32_st<64>(s + (k + 1) * 64 + j + t, TR);
                _mm256_store_si256((__m256i *)v, _mm256_unpacklo_epi16(x, y));
                _mm256_store_si256((__m256i *)(v + 16), _mm256_unpackhi_epi16(x, y));
                v += 32;
            }
            j += w;
        }
    }
}
// one 64x64 packed tile from the dense window (4 sub-leaves; BR sub-leaf is the transformed one)
template<bool Right> static inline void pack_t64_st(U *d, const U *s) {
    pack_leaf32_st<Right, false>(d, s);
    pack_leaf32_st<Right, false>(d + 1040, s + 32);
    pack_leaf32_st<Right, false>(d + 2080, s + 32 * 64);
    pack_leaf32_st<Right, true >(d + 3120, s + 32 * 64 + 32);
}


template<bool Right>
static void pack_four(U *tile,const U *s) {
    pack(tile,s,64,4096,Right);
    pack(tile+HQ,s+2048,64,4096,Right);
    pack(tile+2*HQ,s+2048*4096,64,4096,Right);
    pack(tile+3*HQ,s+2048*4096+2048,64,4096,Right);
}
template<bool Right,bool High>
static void emit_root64(const U *tile,const U *left,const U *right,int offset,U *dest,U *destq,int voff) {
  U *r0=destq+offset,*r1=r0+RS,*r2=r1+RS,*v7=dest+offset+voff*RS,*v5=v7+RS,*v6=v5+RS,*v34=v6+RS;
  for(int i=0;i<(64*64+(64/BASE)*(64/BASE)*TILE_PAD);i+=32){
   __m256i a=ld(tile+i),b=ld(tile+(64*64+(64/BASE)*(64/BASE)*TILE_PAD)+i),c=ld(tile+2*(64*64+(64/BASE)*(64/BASE)*TILE_PAD)+i),d=ld(tile+3*(64*64+(64/BASE)*(64/BASE)*TILE_PAD)+i);
   __m256i aa=ld(tile+i+16),bb=ld(tile+(64*64+(64/BASE)*(64/BASE)*TILE_PAD)+i+16),cc=ld(tile+2*(64*64+(64/BASE)*(64/BASE)*TILE_PAD)+i+16),dd=ld(tile+3*(64*64+(64/BASE)*(64/BASE)*TILE_PAD)+i+16);
   if constexpr(High) {
    a=_mm256_add_epi16(a,_mm256_sub_epi16(ld(left+0*HQ+i),ld(right+0*HQ+i)));
    b=_mm256_add_epi16(b,_mm256_sub_epi16(ld(left+1*HQ+i),ld(right+1*HQ+i)));
    c=_mm256_add_epi16(c,_mm256_sub_epi16(ld(left+2*HQ+i),ld(right+2*HQ+i)));
    d=_mm256_add_epi16(d,_mm256_sub_epi16(ld(left+3*HQ+i),ld(right+3*HQ+i)));
    aa=_mm256_add_epi16(aa,_mm256_sub_epi16(ld(left+0*HQ+i+16),ld(right+0*HQ+i+16)));
    bb=_mm256_add_epi16(bb,_mm256_sub_epi16(ld(left+1*HQ+i+16),ld(right+1*HQ+i+16)));
    cc=_mm256_add_epi16(cc,_mm256_sub_epi16(ld(left+2*HQ+i+16),ld(right+2*HQ+i+16)));
    dd=_mm256_add_epi16(dd,_mm256_sub_epi16(ld(left+3*HQ+i+16),ld(right+3*HQ+i+16)));
   }
   _mm256_stream_si256((__m256i*)(r0+i),a);_mm256_stream_si256((__m256i*)(r0+i+16),aa);
   _mm256_stream_si256((__m256i*)(r1+i),Right?c:b);_mm256_stream_si256((__m256i*)(r1+i+16),Right?cc:bb);
   _mm256_stream_si256((__m256i*)(r2+i),d);_mm256_stream_si256((__m256i*)(r2+i+16),dd);
   __m256i x7=Right?_mm256_sub_epi16(d,b):_mm256_sub_epi16(a,c);
   __m256i xx7=Right?_mm256_sub_epi16(dd,bb):_mm256_sub_epi16(aa,cc);
   _mm256_stream_si256((__m256i*)(v7+i),x7);_mm256_stream_si256((__m256i*)(v7+i+16),xx7);
   __m256i x5=Right?_mm256_sub_epi16(b,a):_mm256_add_epi16(c,d);
   __m256i xx5=Right?_mm256_sub_epi16(bb,aa):_mm256_add_epi16(cc,dd);
   _mm256_stream_si256((__m256i*)(v5+i),x5);_mm256_stream_si256((__m256i*)(v5+i+16),xx5);
   __m256i x6=Right?_mm256_sub_epi16(d,x5):_mm256_sub_epi16(x5,a);
   __m256i xx6=Right?_mm256_sub_epi16(dd,xx5):_mm256_sub_epi16(xx5,aa);
   _mm256_stream_si256((__m256i*)(v6+i),x6);_mm256_stream_si256((__m256i*)(v6+i+16),xx6);
   __m256i x34=Right?_mm256_sub_epi16(x6,c):_mm256_sub_epi16(b,x6);
   __m256i xx34=Right?_mm256_sub_epi16(xx6,cc):_mm256_sub_epi16(bb,xx6);
   _mm256_stream_si256((__m256i*)(v34+i),x34);_mm256_stream_si256((__m256i*)(v34+i+16),xx34);
  }
}
// ======================= BAND-MAJOR STAGED traversal =======================
// 1 MB window = 2 bands x 64 dense 64x64 tiles (tile t of band b at stag + (b*64+t)*4096)
alignas(4096) static U stag[128 * 4096];
static U hlbuf[16 * 4 * HQ];        // k=1 ("high_left") tiles, one per region column

static long qh(long h) { return h * h + (h / BASE) * (h / BASE) * TILE_PAD; }
static inline long off64(int R, int C) {           // dest offset of the 64-tile at (R,C)
    int r = R & ~127, c = C & ~127;
    long o = 0;
    const int hs[4] = {1024, 512, 256, 128};
    for (int i = 0; i < 4; ++i) {
        int h = hs[i], m = 2 * h;
        int qi = 2 * (((r % m) >= h) ? 1 : 0) + (((c % m) >= h) ? 1 : 0);
        o += qh(h) * qi;
    }
    return o + (long)(((R & 64) ? 2 : 0) + ((C & 64) ? 1 : 0)) * HQ;
}
// sequential source read -> dense 64x64 tiles
static inline void stage_band(U *W, const U *src) {
    for (int r = 0; r < 64; ++r) {
        const U *q = src + (size_t)r * 4096;
        for (int j = 0; j < 64; ++j) {
            U *d = W + (size_t)j * 4096 + (size_t)r * 64;
            const U *p = q + j * 64;
            for (int t = 0; t < 4; ++t)
                _mm256_store_si256((__m256i *)(d + t * 16), _mm256_loadu_si256((const __m256i *)(p + t * 16)));
        }
    }
}
// one pack_four source set from the window: tiles (R,C) and (R,C+2048) in band 0/1
template<bool Right> static inline void pack_four_st(U *tile, const U *W, int C) {
    int j = C >> 6;
    {
        pack_t64_st<Right>(tile,           W + (size_t)j * 4096);
        pack_t64_st<Right>(tile + HQ,      W + (size_t)(j + 32) * 4096);
        pack_t64_st<Right>(tile + 2 * HQ,  W + (size_t)(64 + j) * 4096);
        pack_t64_st<Right>(tile + 3 * HQ,  W + (size_t)(64 + j + 32) * 4096);
    }
}
template<bool Right> static void pack_staged(const U *src, U *dest, U *destq, int voff) {
#pragma GCC unroll 1
    for (int R = 0; R < 2048; R += 64) {
        {
            stage_band(stag, src + (size_t)R * 4096);
            stage_band(stag + 64 * 4096, src + (size_t)(R + 2048) * 4096);
        }
        const bool hirow = (R & 64) != 0;
#pragma GCC unroll 1
        for (int C = 0; C < 2048; C += 64) {
            long E = off64(R, C);
            if (!hirow) {
                if (!(C & 64)) {
                    pack_four_st<Right>(root_tile, stag, C);
                    emit_root64<Right, false>(root_tile, nullptr, nullptr, E, dest, destq, voff);
                } else {
                    U *hl = hlbuf + (size_t)(C >> 7) * (4 * HQ);
                    pack_four_st<Right>(hl, stag, C);
                    emit_root64<Right, false>(hl, nullptr, nullptr, E, dest, destq, voff);
                }
            } else {
                if (!(C & 64)) {
                    pack_four_st<Right>(high_right, stag, C);
                    emit_root64<Right, false>(high_right, nullptr, nullptr, E, dest, destq, voff);
                } else {
                    U *hl = hlbuf + (size_t)(C >> 7) * (4 * HQ);
                    pack_four_st<Right>(root_tile, stag, C);
                    emit_root64<Right, true>(root_tile, hl, high_right, E, dest, destq, voff);
                }
            }
        }
    }
}


template<bool Right>
static void pack_root(const U*s,int n,int offset,U *dest,U *destq,int voff) {
    if(n>128){int h=n/2,q=h*h+(h/BASE)*(h/BASE)*TILE_PAD;
        pack_root<Right>(s,h,offset,dest,destq,voff);
        pack_root<Right>(s+h,h,offset+q,dest,destq,voff);
        pack_root<Right>(s+h*4096,h,offset+2*q,dest,destq,voff);
        pack_root<Right>(s+h*4096+h,h,offset+3*q,dest,destq,voff);
    } else {
        pack_four<Right>(root_tile,s);
        emit_root64<Right,false>(root_tile,nullptr,nullptr,offset,dest,destq,voff);
        pack_four<Right>(high_left,s+64);
        emit_root64<Right,false>(high_left,nullptr,nullptr,offset+HQ,dest,destq,voff);
        pack_four<Right>(high_right,s+64*4096);
        emit_root64<Right,false>(high_right,nullptr,nullptr,offset+2*HQ,dest,destq,voff);
        pack_four<Right>(root_tile,s+64*4096+64);
        emit_root64<Right,true>(root_tile,high_left,high_right,offset+3*HQ,dest,destq,voff);
    }
}
void matrix_multiply(int n,const short*A,const short*B,short*C){
 U *cq=(U*)C; // Three root input slots and the retired tail precede final C writeback.
 U *ar=root_mem,*br=ar+4*RS,*pr=br+7*RS;   // root_mem 15 -> 12 槽
 U *work=cq+3*RS+(464*2);
 pack_staged<false>((const U*)A,ar,cq,0);
 pack_staged<true>((const U*)B,br,br,3);
 _mm_mfence();
 const U *a11=cq,*a12=cq+RS,*a22=cq+2*RS,*s7=ar,*s5=ar+RS,*s6=ar+2*RS,*s3=ar+3*RS;
 const U *b11=br,*b21=br+RS,*b22=br+2*RS,*t7=br+3*RS,*t5=br+4*RS,*t6=br+5*RS,*t4=br+6*RS;
 U *p1=ar+2*RS,*p2=br+5*RS,*p3=ar+RS,*p4=br+4*RS,*p5=ar,*p6=br+3*RS,*p7=pr;
 mul<2048>(s7,t7,p7,work);mul<2048>(s5,t5,p5,work);mul<2048>(s6,t6,p6,work);
 mul<2048>(s3,b22,p3,work);mul<2048>(a22,t4,p4,work);mul<2048>(a11,b11,p1,work);mul<2048>(a12,b21,p2,work);
 U *out=(U*)C;
 root_fuse<2048>(out,out+2048,out+2048*4096,out+2048*4096+2048,p1,p2,p3,p4,p5,p6,p7,4096);_mm_sfence();
 asm volatile(".purgem vzeroupper");
 _mm256_zeroupper();
}


CompilationN/AN/ACompile OKScore: N/A

Testcase #1532.648 ms131 MB + 108 KBAcceptedScore: 100


Judge Duck Online | 评测鸭在线
Server Time: 2026-11-04 18:13:58 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠