提交记录 118474


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_cc_v41_agg1 mmms4k. 测测你的短整数矩阵乘法-4k Accepted 100 546.533 ms 132696 KB C++17 62.78 KB
提交时间 评测时间
2026-10-01 11:10:31 2026-10-01 11:10:35
// ===== REFERENCES =====
// [1] 正文 lineage(逐字节移植):对手 **pdoom** 的 **#118412**
//     <https://duck.ac/submission/118412>(judge 545705.580 ms,现役 rank 1);
//     本账号的移植件 **#118433** <https://duck.ac/submission/118433>(545737.517 ms = 本账号现役最好)。
//     许可:duck.ac 题目页明示「你提交的代码将会被公开」,对手正文同属该站公开提交
//     (本项目 tools/copy_ref.py · fetch_rival.py · rivalcopy.py 均为同一用途的既定工具)。
// [2] 本席(s4bq_)对 `pack_root`/`pack` 的仪器与定价(全部 in-repo 可复现):
//     * 判题机 custom-test 冷/暖分离(work/s4bq_gen.py 的 base[-rep3] 臂,rdtsc 插桩两个 pack_root 调用):
//       冷 28.66/29.34 M 拍 ⟷ 暖 18.78/19.28 M 拍 ⇒ 冷溢价 19.94 M 拍 = 29 120 页 × **685 拍/页**;
//       预触页臂(37 441 页 = 33.10 M 拍 = 884 拍/页)后**全部** pack 调用落到暖水位
//       ⇒ 冷溢价 100% 是缺页,且预触页(884)比引擎内(685)贵 ⇒ 「预落页」结构性净负(与 (1368) 独立互证)。
//     * 双热消融(读/写各换到热缓冲):暖 A 18.78 = 读 10.33 + 写 3.36 + 核 6.64 M;暖 B 19.25 = 读 9.03 + 写 3.91 + 核 7.50 M。
//     * 合成上限(判题机):顺序读 26 GB/s · 本件读序 13.9 GB/s · 行组扫描序 24 GB/s(1.9x)· 融合 4 相邻叶 22 GB/s;
//       7 流 NT 写 32 GB/s;**同字节理想混合 = 12.6~15.0 M 拍** ⟷ 真 pack 18.8~19.2 M ⇒ 本件坐在混合带宽墙上。
//     * 软件预取(A 侧 PD=4/8/16、B 侧 8,逐位等价):判题机 **0~+1.7 M(负)**。
//     * 「n=128 融合叶对」(相邻两叶按行组交错读,合成里读序改善 1.6x):判题机 **+0.55 M(A) / +1.74 M(B)**;
//       原序对照 refactor-only **+0.60 / +0.88 M** ⇒ 读序本身在位内为负。
//     * 槽步长相位扫描(ROOT_PAD 32/48/64/96/128/160/256/1024/2048/4128):除 +96 B 相位(行重叠,+2.5 M)外全在 ±0.15 M ⇒ 现役即最优。
// [3] 本件用途:**仪器校验件(不是改进件)** —— 把 [2] 里「pack 相位 +Δ 拍」的预测送到**板面**,
//     回答全队悬案:探针通道的 **pack 相位**读数能否预测板面((1349) 只说整程序口径对载入/存储类不可信)。
//     预测:本件板面应比同批锚慢 **+0.42 ms**(pack 相位 +1.48 M 拍 / 3.556 GHz);若板面实测落在 0±0.15 ms
//     ⇒ 该通道对 pack 亦不可信(新仪器律);若落在 +0.3~+0.6 ms ⇒ 通道可用,后续席位可用探针廉价定价 pack 改动。
// ======================
// ===== 思路 =====
// 逐位等价重构(ck = 9901480129097868163,本机 + 判题机双侧一致):
//   把 `pack_root` 的 n=64 基例拆成三个可复用函数
//   (pk_rows_l/pk_rows_r = 一个行组/一对行;leaf_emit = 4-tile scratch 落 7 路流),
//   并在 n==128 处分派到 `pack_leaf2`(一次处理 n=128 节点的 4 个叶)。
//   **本件保持原叶序**(每个叶的 4 个 tile 依次跑完,A 叶跑完再跑 B 叶),
//   仅改代码组织与 scratch 尺寸(root_tile 4*4096 → 32768 元素)⇒ 输出逐位不变。
// 用途:作为「融合叶对」的**同码对照**,供板面把「重排读序」与「重构/代码尺寸」两个因素分开。
// ================
/*
Credit:
saffah_cc_v41_agg1 #118236, https://duck.ac/submission/118236 : three-madd
scheduling, fused four-quadrant root output, borrowing C for root raw inputs,
and shift/blend truncation with deferred inverse word permutation.
Oded Schwartz and Noa Vaknin, Pebbling Game and Alternative Basis for High
Performance Matrix Multiplication, SIAM J. Sci. Comput. (2023), (3.1): the
exact seven-product, twelve-add alternative-basis decomposition over a ring.
https://epubs.siam.org/doi/10.1137/22M1502719

Retained lineage:
pdoom #86352, https://duck.ac/submission/86352 : exact mod-65536 engine,
recursive packing and AVX2 pair-dot products; #112312 : fused root packing,
retired input slot reuse, complete cache-line streams and padded leaf offsets;
#117569 : SIMD-native leaf output, delayed root decode and one panel asm body.
saffah_cc_v41_agg1 #112006/#117247 : peeled first pair, operand/output packing,
cache offsets, three-row tail scheduling and compiler scheduling options.
saffah_codex_6s_agg2 #110387/#102935 : fused root reconstruction, constant
recursion and instruction order. saffah_cc_v41_260924 #96771 : cache phases.

New pdoom changes in this version:
- At N=128 use the ring-valid twelve-add bilinear graph in alternative bases.
  A fixed basis commutes with every upper-level linear combination. Apply
  the input maps in the first raw loads and the inverse output map in the
  final root reconstruction; no whole packed-matrix transform scans.
- Keep 64x64 leaves. The 24-column panel kernel peels two k-pairs and loops
  six pairs. The tail peels eight pairs and loops four, holding all four
  rows' products before adding;
  the cached B register becomes the last row's product after its last use.
- Use C's dead tail for the recursive work area, before final C writeback.
- Preserve padding/cache phases, but never add or load/store padding values.
Every input and output is exact in Z/(2^16); no distribution assumption.
Specialized to the stated n=4096, separately allocated aligned matrices.
*/
#define ALTMAX 128
#define ROOT_PAD 32
#pragma GCC optimize("O3,unroll-loops,web,rename-registers")
#pragma GCC target("avx2")
#include <immintrin.h>
#include <stdint.h>
#include <string.h>
#include <initializer_list>

#ifndef TILE_PAD
#define TILE_PAD 64
#endif
#ifndef BASE
#define BASE (1 << 6)
#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_basis32(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-64*4096)),
  _mm256_loadu_si256((const __m256i*)(p-64))));
 return v;
}
static inline __m128i raw_basis16(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-64*4096)),
  _mm_loadu_si128((const __m128i*)(p-64))));
 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 bool transformed=((s-raw_basis_input)&64) && ((s-raw_basis_input)&(64*4096));
        for(int i=0;i<n;i+=4) for(int k=0;k<n;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 bool transformed=((s-raw_basis_input)&64) && ((s-raw_basis_input)&(64*4096));
        for(int k=0;k<n;k+=2) for(int j=0;j<n;) {
            int w=n-j>=24?24:n-j;
            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=raw_basis16(s+k*stride+j+t,transformed);
                    __m128i y=raw_basis16(s+(k+1)*stride+j+t,transformed);
                    _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.
static inline void native24_panels(const U *a,const U *b,U *c) {
    U *tail=c+192;
    const U *end=a+256,*a_final=a+4096;
    intptr_t panels=2;
    asm volatile(
        "3:\n\t"
        "vmovdqa 0(%[b]), %%ymm12\n\t"
        "vpbroadcastd 0(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm0\n\t"
        "vpmaddwd 32(%[b]), %%ymm14, %%ymm1\n\t"
        "vpmaddwd 64(%[b]), %%ymm14, %%ymm2\n\t"
        "vpbroadcastd 4(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm3\n\t"
        "vpmaddwd 32(%[b]), %%ymm14, %%ymm4\n\t"
        "vpmaddwd 64(%[b]), %%ymm14, %%ymm5\n\t"
        "vpbroadcastd 8(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm6\n\t"
        "vpmaddwd 32(%[b]), %%ymm14, %%ymm7\n\t"
        "vpmaddwd 64(%[b]), %%ymm14, %%ymm8\n\t"
        "vpbroadcastd 12(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm9\n\t"
        "vpmaddwd 32(%[b]), %%ymm14, %%ymm10\n\t"
        "vpmaddwd 64(%[b]), %%ymm14, %%ymm11\n\t"
        "vmovdqa 96(%[b]), %%ymm12\n\t"
        "vpbroadcastd 16(%[a]), %%ymm14\n\t"
        "vpmaddwd 128(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 20(%[a]), %%ymm14\n\t"
        "vpmaddwd 128(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm13, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpbroadcastd 24(%[a]), %%ymm14\n\t"
        "vpmaddwd 128(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm13, %%ymm7, %%ymm7\n\t"
        "vpaddd %%ymm14, %%ymm8, %%ymm8\n\t"
        "vpbroadcastd 28(%[a]), %%ymm14\n\t"
        "vpmaddwd 128(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm13, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "add $32, %[a]\n\t"
        "add $192, %[b]\n\t"
        "1:\n\t"
        "vmovdqa 0(%[b]), %%ymm12\n\t"
        "vpbroadcastd 0(%[a]), %%ymm14\n\t"
        "vpmaddwd 32(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 64(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 4(%[a]), %%ymm14\n\t"
        "vpmaddwd 32(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 64(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm13, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpbroadcastd 8(%[a]), %%ymm14\n\t"
        "vpmaddwd 32(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 64(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm13, %%ymm7, %%ymm7\n\t"
        "vpaddd %%ymm14, %%ymm8, %%ymm8\n\t"
        "vpbroadcastd 12(%[a]), %%ymm14\n\t"
        "vpmaddwd 32(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 64(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm13, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "vmovdqa 96(%[b]), %%ymm12\n\t"
        "vpbroadcastd 16(%[a]), %%ymm14\n\t"
        "vpmaddwd 128(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 20(%[a]), %%ymm14\n\t"
        "vpmaddwd 128(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm13, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpbroadcastd 24(%[a]), %%ymm14\n\t"
        "vpmaddwd 128(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm13, %%ymm7, %%ymm7\n\t"
        "vpaddd %%ymm14, %%ymm8, %%ymm8\n\t"
        "vpbroadcastd 28(%[a]), %%ymm14\n\t"
        "vpmaddwd 128(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm13, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "vmovdqa 192(%[b]), %%ymm12\n\t"
        "vpbroadcastd 32(%[a]), %%ymm14\n\t"
        "vpmaddwd 224(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 256(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 36(%[a]), %%ymm14\n\t"
        "vpmaddwd 224(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 256(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm13, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpbroadcastd 40(%[a]), %%ymm14\n\t"
        "vpmaddwd 224(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 256(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm13, %%ymm7, %%ymm7\n\t"
        "vpaddd %%ymm14, %%ymm8, %%ymm8\n\t"
        "vpbroadcastd 44(%[a]), %%ymm14\n\t"
        "vpmaddwd 224(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 256(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm13, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "vmovdqa 288(%[b]), %%ymm12\n\t"
        "vpbroadcastd 48(%[a]), %%ymm14\n\t"
        "vpmaddwd 320(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 352(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 52(%[a]), %%ymm14\n\t"
        "vpmaddwd 320(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 352(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm13, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpbroadcastd 56(%[a]), %%ymm14\n\t"
        "vpmaddwd 320(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 352(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm13, %%ymm7, %%ymm7\n\t"
        "vpaddd %%ymm14, %%ymm8, %%ymm8\n\t"
        "vpbroadcastd 60(%[a]), %%ymm14\n\t"
        "vpmaddwd 320(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 352(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm13, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "vmovdqa 384(%[b]), %%ymm12\n\t"
        "vpbroadcastd 64(%[a]), %%ymm14\n\t"
        "vpmaddwd 416(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 448(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 68(%[a]), %%ymm14\n\t"
        "vpmaddwd 416(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 448(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm13, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpbroadcastd 72(%[a]), %%ymm14\n\t"
        "vpmaddwd 416(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 448(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm13, %%ymm7, %%ymm7\n\t"
        "vpaddd %%ymm14, %%ymm8, %%ymm8\n\t"
        "vpbroadcastd 76(%[a]), %%ymm14\n\t"
        "vpmaddwd 416(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 448(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm13, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "vmovdqa 480(%[b]), %%ymm12\n\t"
        "vpbroadcastd 80(%[a]), %%ymm14\n\t"
        "vpmaddwd 512(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 544(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm14, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 84(%[a]), %%ymm14\n\t"
        "vpmaddwd 512(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 544(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm13, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpbroadcastd 88(%[a]), %%ymm14\n\t"
        "vpmaddwd 512(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 544(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm13, %%ymm7, %%ymm7\n\t"
        "vpaddd %%ymm14, %%ymm8, %%ymm8\n\t"
        "vpbroadcastd 92(%[a]), %%ymm14\n\t"
        "vpmaddwd 512(%[b]), %%ymm14, %%ymm13\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 544(%[b]), %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm15, %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm13, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "add $96, %[a]\n\t"
        "add $576, %[b]\n\t"
        "cmp %[end], %[a]\n\t"
        "jb 1b\n\t"
        "2:\n\t"
        "vmovdqa s4aj_m16(%%rip), %%ymm13\n\t"
        "vpslld $16, %%ymm1, %%ymm1\n\t"
        "vpblendw $0xAA, %%ymm1, %%ymm0, %%ymm0\n\t"
        "vmovdqu %%ymm0, 0(%[c])\n\t"
        "vpslld $16, %%ymm4, %%ymm4\n\t"
        "vpblendw $0xAA, %%ymm4, %%ymm3, %%ymm3\n\t"
        "vmovdqu %%ymm3, 32(%[c])\n\t"
        "vpslld $16, %%ymm7, %%ymm7\n\t"
        "vpblendw $0xAA, %%ymm7, %%ymm6, %%ymm6\n\t"
        "vmovdqu %%ymm6, 64(%[c])\n\t"
        "vpslld $16, %%ymm10, %%ymm10\n\t"
        "vpblendw $0xAA, %%ymm10, %%ymm9, %%ymm9\n\t"
        "vmovdqu %%ymm9, 96(%[c])\n\t"
        "vpslld $16, %%ymm5, %%ymm5\n\t"
        "vpblendw $0xAA, %%ymm5, %%ymm2, %%ymm2\n\t"
        "vmovdqu %%ymm2, 0(%[tail])\n\t"
        "vpslld $16, %%ymm11, %%ymm11\n\t"
        "vpblendw $0xAA, %%ymm11, %%ymm8, %%ymm8\n\t"
        "vmovdqu %%ymm8, 32(%[tail])\n\t"

        "add $512, %[c]\n\t"
        "add $512, %[tail]\n\t"
        "sub $3072, %[b]\n\t"
        "add $512, %[end]\n\t"
        "cmp %[a_final], %[a]\n\t"
        "jb 3b\n\t"
        "sub $8192, %[a]\n\t"
        "sub $8192, %[end]\n\t"
        "add $3072, %[b]\n\t"
        "sub $8064, %[c]\n\t"
        "sub $8128, %[tail]\n\t"
        "dec %[panels]\n\t"
        "jnz 3b\n\t"
        : [a] "+&r"(a), [b] "+&r"(b), [c] "+&r"(c),
          [tail] "+&r"(tail), [end] "+&r"(end), [panels] "+&r"(panels)
        : [a_final] "r"(a_final)
        : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15");
}

static inline void micro16(const U *a,const U *b,U *c,int n){
 const U *end=a+4*n;
 asm volatile(
        "vmovdqa 0(%[b]), %%ymm8\n\t"
        "vpbroadcastd 0(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm0\n\t"
        "vpmaddwd 32(%[b]), %%ymm10, %%ymm1\n\t"
        "vpbroadcastd 4(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm2\n\t"
        "vpmaddwd 32(%[b]), %%ymm10, %%ymm3\n\t"
        "vpbroadcastd 8(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm4\n\t"
        "vpmaddwd 32(%[b]), %%ymm10, %%ymm5\n\t"
        "vpbroadcastd 12(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm6\n\t"
        "vpmaddwd 32(%[b]), %%ymm10, %%ymm7\n\t"
        "vmovdqa 64(%[b]), %%ymm8\n\t"
        "vpbroadcastd 16(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 96(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 20(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 96(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 24(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 96(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 28(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 96(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "vmovdqa 128(%[b]), %%ymm8\n\t"
        "vpbroadcastd 32(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 160(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 36(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 160(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 40(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 44(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 160(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "vmovdqa 192(%[b]), %%ymm8\n\t"
        "vpbroadcastd 48(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 224(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 52(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 224(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 56(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 224(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 60(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 224(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "vmovdqa 256(%[b]), %%ymm8\n\t"
        "vpbroadcastd 64(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 288(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 68(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 288(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 72(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 288(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 76(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 288(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "vmovdqa 320(%[b]), %%ymm8\n\t"
        "vpbroadcastd 80(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 352(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 84(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 352(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 88(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 352(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 92(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 352(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "vmovdqa 384(%[b]), %%ymm8\n\t"
        "vpbroadcastd 96(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 416(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 100(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 416(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 104(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 416(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 108(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 416(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "vmovdqa 448(%[b]), %%ymm8\n\t"
        "vpbroadcastd 112(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 480(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 116(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 480(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 120(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 480(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 124(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 480(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "add $128, %[a]\n\t"
        "add $512, %[b]\n\t"
        "1:\n\t"
        "vmovdqa 0(%[b]), %%ymm8\n\t"
        "vpbroadcastd 0(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 32(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 4(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 32(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 8(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 32(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 12(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 32(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "vmovdqa 64(%[b]), %%ymm8\n\t"
        "vpbroadcastd 16(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 96(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 20(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 96(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 24(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 96(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 28(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 96(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "vmovdqa 128(%[b]), %%ymm8\n\t"
        "vpbroadcastd 32(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 160(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 36(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 160(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 40(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 160(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 44(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 160(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "vmovdqa 192(%[b]), %%ymm8\n\t"
        "vpbroadcastd 48(%[a]), %%ymm10\n\t"
        "vpmaddwd %%ymm8, %%ymm10, %%ymm11\n\t"
        "vpmaddwd 224(%[b]), %%ymm10, %%ymm10\n\t"
        "vpbroadcastd 52(%[a]), %%ymm12\n\t"
        "vpmaddwd %%ymm8, %%ymm12, %%ymm13\n\t"
        "vpmaddwd 224(%[b]), %%ymm12, %%ymm12\n\t"
        "vpbroadcastd 56(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm8, %%ymm14, %%ymm15\n\t"
        "vpmaddwd 224(%[b]), %%ymm14, %%ymm14\n\t"
        "vpbroadcastd 60(%[a]), %%ymm9\n\t"
        "vpmaddwd %%ymm8, %%ymm9, %%ymm8\n\t"
        "vpmaddwd 224(%[b]), %%ymm9, %%ymm9\n\t"
        "vpaddd %%ymm11, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm10, %%ymm1, %%ymm1\n\t"
        "vpaddd %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm12, %%ymm3, %%ymm3\n\t"
        "vpaddd %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vpaddd %%ymm8, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm9, %%ymm7, %%ymm7\n\t"
        "add $64, %[a]\n\t"
        "add $256, %[b]\n\t"
        "cmp %[end], %[a]\n\t"
        "jb 1b\n\t"
        "vpslld $16, %%ymm1, %%ymm1\n\t"
        "vpblendw $0xAA, %%ymm1, %%ymm0, %%ymm0\n\t"
        "vmovdqu %%ymm0, 0(%[c])\n\t"
        "vpslld $16, %%ymm3, %%ymm3\n\t"
        "vpblendw $0xAA, %%ymm3, %%ymm2, %%ymm2\n\t"
        "vmovdqu %%ymm2, 32(%[c])\n\t"
        "vpslld $16, %%ymm5, %%ymm5\n\t"
        "vpblendw $0xAA, %%ymm5, %%ymm4, %%ymm4\n\t"
        "vmovdqu %%ymm4, 64(%[c])\n\t"
        "vpslld $16, %%ymm7, %%ymm7\n\t"
        "vpblendw $0xAA, %%ymm7, %%ymm6, %%ymm6\n\t"
        "vmovdqu %%ymm6, 96(%[c])\n\t"
 : [a] "+&r"(a), [b] "+&r"(b)
 : [c] "r"(c), [end] "r"(end)
 : "cc", "memory", "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15");
}
static inline void micro8(const U *a,const U *b,U *c,int n) {
    const U *end=a+4*n; U *c3=c+3*n; intptr_t stride=2*n;
    asm volatile(
        "vmovdqa 0(%[b]), %%ymm12\n\t"
        "vpbroadcastd 0(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm0\n\t"
        "vpbroadcastd 4(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm1\n\t"
        "vpbroadcastd 8(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm2\n\t"
        "vpbroadcastd 12(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm3\n\t"
        "vmovdqa 32(%[b]), %%ymm12\n\t"
        "vpbroadcastd 16(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 20(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 24(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 28(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 64(%[b]), %%ymm12\n\t"
        "vpbroadcastd 32(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 36(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 40(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 44(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 96(%[b]), %%ymm12\n\t"
        "vpbroadcastd 48(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 52(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 56(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 60(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 128(%[b]), %%ymm12\n\t"
        "vpbroadcastd 64(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 68(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 72(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 76(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 160(%[b]), %%ymm12\n\t"
        "vpbroadcastd 80(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 84(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 88(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 92(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 192(%[b]), %%ymm12\n\t"
        "vpbroadcastd 96(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 100(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 104(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 108(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 224(%[b]), %%ymm12\n\t"
        "vpbroadcastd 112(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 116(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 120(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 124(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "add $128, %[a]\n\t"
        "add $256, %[b]\n\t"
        "1:\n\t"
        "vmovdqa 0(%[b]), %%ymm12\n\t"
        "vpbroadcastd 0(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 4(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 8(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 12(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 32(%[b]), %%ymm12\n\t"
        "vpbroadcastd 16(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 20(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 24(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 28(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 64(%[b]), %%ymm12\n\t"
        "vpbroadcastd 32(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 36(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 40(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 44(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 96(%[b]), %%ymm12\n\t"
        "vpbroadcastd 48(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 52(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 56(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 60(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 128(%[b]), %%ymm12\n\t"
        "vpbroadcastd 64(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 68(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 72(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 76(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 160(%[b]), %%ymm12\n\t"
        "vpbroadcastd 80(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 84(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 88(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 92(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 192(%[b]), %%ymm12\n\t"
        "vpbroadcastd 96(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 100(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 104(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 108(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "vmovdqa 224(%[b]), %%ymm12\n\t"
        "vpbroadcastd 112(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpbroadcastd 116(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm1, %%ymm1\n\t"
        "vpbroadcastd 120(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpbroadcastd 124(%[a]), %%ymm14\n\t"
        "vpmaddwd %%ymm12, %%ymm14, %%ymm15\n\t"
        "vpaddd %%ymm15, %%ymm3, %%ymm3\n\t"
        "add $128, %[a]\n\t"
        "add $256, %[b]\n\t"
        "cmp %[end], %[a]\n\t"
        "jb 1b\n\t"
        "2:\n\t"
        "vpcmpeqd %%ymm13, %%ymm13, %%ymm13\n\t"
        "vpsrld $16, %%ymm13, %%ymm13\n\t"
        "vpand %%ymm13, %%ymm0, %%ymm0\n\t"
        "vpackusdw %%ymm0, %%ymm0, %%ymm0\n\t"
        "vpermq $216, %%ymm0, %%ymm0\n\t"
        "vmovdqu %%xmm0, 0(%[c])\n\t"
        "vpand %%ymm13, %%ymm1, %%ymm1\n\t"
        "vpackusdw %%ymm1, %%ymm1, %%ymm1\n\t"
        "vpermq $216, %%ymm1, %%ymm1\n\t"
        "vmovdqu %%xmm1, 0(%[c],%[s],1)\n\t"
        "vpand %%ymm13, %%ymm2, %%ymm2\n\t"
        "vpackusdw %%ymm2, %%ymm2, %%ymm2\n\t"
        "vpermq $216, %%ymm2, %%ymm2\n\t"
        "vmovdqu %%xmm2, 0(%[c],%[s],2)\n\t"
        "vpand %%ymm13, %%ymm3, %%ymm3\n\t"
        "vpackusdw %%ymm3, %%ymm3, %%ymm3\n\t"
        "vpermq $216, %%ymm3, %%ymm3\n\t"
        "vmovdqu %%xmm3, 0(%[c3])\n\t"
        : [a] "+&r"(a), [b] "+&r"(b)
        : [c] "r"(c), [c3] "r"(c3), [s] "r"(stride), [end] "r"(end)
        : "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) {
    native24_panels(a,b,c);
    for(int i=0;i<64;i+=4)
        micro16(a+i*64,b+48*64,c+i*64+128,64);
}

// The result of each four-row leaf block occupies 16 YMM vectors:
// 4 main vectors for columns 0..15, 4 for 24..39, 4 for 48..63,
// and 2 adjacent-row tail pairs for each of 16..23 and 40..47.
template<int Col>
static inline __m256i decode_native(const U *s,int row) {
    if constexpr(Col==0) return s4bj_fx(ld(s+16*row));
    if constexpr(Col==48) return s4bj_fx(ld(s+128+16*row));
    __m256i mid=s4bj_fx(ld(s+64+16*row));
    if constexpr(Col==16) {
        __m256i tail=_mm256_permute4x64_epi64(s4bj_fx(ld(s+192+(row/2)*16)),0xd8);
        return row%2 ? _mm256_permute2x128_si256(tail,mid,0x21)
                     : _mm256_permute2x128_si256(tail,mid,0x20);
    } else {
        __m256i tail=_mm256_permute4x64_epi64(s4bj_fx(ld(s+224+(row/2)*16)),0xd8);
        return row%2 ? _mm256_permute2x128_si256(mid,tail,0x31)
                     : _mm256_permute2x128_si256(mid,tail,0x21);
    }
}
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),decode_native<0>(s,row));
        _mm256_stream_si256((__m256i*)(d+16),decode_native<16>(s,row));
        _mm256_stream_si256((__m256i*)(d+32),decode_native<32>(s,row));
        _mm256_stream_si256((__m256i*)(d+48),decode_native<48>(s,row));
    }
}

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+=4096+TILE_PAD) {
      #pragma GCC unroll 4
      for(int j=0;j<4096;j+=16) {
        int i=chunk+j;
        __m256i x=ld(a+i),y=ld(b+i);
        st(d+i,Sub?_mm256_sub_epi16(x,y):_mm256_add_epi16(x,y));
      }
    }
}

// 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*256];
        for(int block=0;block<4096;block=block+256) {
            for(int v=0;v<256;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+256+v,_mm256_sub_epi16(u3,ld(p4+idx)));
                st(temp+512+v,_mm256_add_epi16(u3,v5));
            }
            size_t off=(size_t)(block/64)*stride;
            emit_native(d12+off,temp,stride);
            emit_native(d21+off,temp+256,stride);
            emit_native(d22+off,temp+512,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[256];
        for(int block=0;block<4096;block+=256) {
            for(int v=0;v<256;v+=16)
                st(temp+v,_mm256_add_epi16(ld(p2+block+v),ld(p1+block+v)));
            emit_native(d+(size_t)(block/64)*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 tmp[3*4*256];
        U *dest[4]={d11,d12,d21,d22};
        for(int block=0;block<4096;block+=256) {
            for(int child=1;child<=3;child++) {
                for(int v=0;v<256;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)*1024;
                    st(t+v,_mm256_add_epi16(v1,ld(p2+idx)));
                    st(t+256+v,_mm256_add_epi16(_mm256_add_epi16(u2,v5),ld(p3+idx)));
                    st(t+512+v,_mm256_sub_epi16(u3,ld(p4+idx)));
                    st(t+768+v,_mm256_add_epi16(u3,v5));
                }
            }
            for(int v=0;v<1024;v+=16) {
                __m256i c22=ld(tmp+2048+v);
                st(tmp+v,_mm256_sub_epi16(ld(tmp+v),c22));
                st(tmp+1024+v,_mm256_sub_epi16(c22,ld(tmp+1024+v)));
            }
            size_t off=(size_t)(block/64)*stride;
            for(int r=0;r<4;r++) {
                emit_native(dest[r]+off+64,tmp+r*256,stride);
                emit_native(dest[r]+off+64*stride,tmp+1024+r*256,stride);
                emit_native(dest[r]+off+64*stride+64,tmp+2048+r*256,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*256];
        for(int block=0;block<4096;block+=256) {
            for(int v=0;v<256;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+256+v,_mm256_sub_epi16(u3,ld(p4+idx)));
                st(temp+512+v,_mm256_add_epi16(u3,v5));
                st(temp+768+v,_mm256_add_epi16(ld(p2+idx),ld(p1+idx)));
            }
            size_t off=(size_t)(block/64)*stride;
            emit_native(d12+off,temp,stride);
            emit_native(d21+off,temp+256,stride);
            emit_native(d22+off,temp+512,stride);
            emit_native(d11+off,temp+768,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,*y=work+q+128,*next=work+2*q+256;
  mul<h>(a12,b21,c11,next);                 // m2
  mul<h>(a22,b22,c22,next);                 // m4
  combine<false>(x,a21,a22,q);
  combine<false>(y,b21,b22,q);
  mul<h>(x,y,c12,next);                     // m5
  combine<true>(x,a22,a12,q);
  combine<true>(y,b22,b12,q);
  mul<h>(x,y,c21,next);                     // m6
  for(int chunk=0;chunk<q;chunk+=4096+TILE_PAD) for(int i=chunk;i<chunk+4096;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))));
  mul<h>(a11,b11,x,next);                   // m1
  combine<false>(c11,c11,x,q);
  combine<true>(y,b22,b11,q);
  mul<h>(a21,y,x,next);                     // m3
  combine<false>(c21,c21,x,q);
  combine<true>(x,a22,a11,q);
  mul<h>(x,b12,y,next);                     // m7
  combine<true>(c12,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+0,*y=work+q+128,*next=work+q+q+256;
    combine<true>(y,b22,b12,q);
    combine<true>(x,a11,a21,q);
    mul<h>(x,y,c21,next);                       // P7
    combine<false>(x,a21,a22,q);
    combine<true>(y,b12,b11,q);
    mul<h>(x,y,c22,next);                       // P5
    combine<true>(x,x,a11,q);
    combine<true>(y,b22,y,q);
    mul<h>(x,y,c12,next);                       // P6
    combine<true>(x,a12,x,q);
    mul<h>(x,b22,c11,next);                     // P3
    combine<true>(y,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+=4096+TILE_PAD) for(int i=chunk;i<chunk+4096;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<false>(c11,c11,y,q);
    }
}


static constexpr int RQ=2048*2048+32*32*TILE_PAD,RS=RQ+ROOT_PAD;
alignas(4096) static U root_mem[15*RS+4096];
alignas(4096) static U root_tile[32768];   // s4bq_: 8*4096 = 融合两叶

#define S4BQ_FUSED 0
// ===== s4bq_ 融合叶对(顺序=原序):把 n=128 的 4 个叶按「相邻列叶 + 行组」交错读 =====
static inline bool pk_tr(const U *s){
  return ((s-raw_basis_input)&64) && ((s-raw_basis_input)&(64*4096));
}
// !right 分支的一个 4 行组(i 为块内行偏移);dst 基址 = 该 tile 的 d + (i/4)*(n/16)*64
static inline void pk_rows_l(U *d,const U *s,int i,int n,int stride,bool transformed){
  for(int k=0;k<n;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;
  }
}
// right 分支的一对行(k = 叶内行号,步长 2)
static inline void pk_rows_r(U *d,const U *s,int k,int n,int stride,bool transformed){
  for(int j=0;j<n;) {
    int w=n-j>=24?24:n-j;
    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=raw_basis16(s+k*stride+j+t,transformed);
        __m128i y=raw_basis16(s+(k+1)*stride+j+t,transformed);
        _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;
  }
}
// 叶输出:从 16K 元素的 4-tile scratch 落 7 路流(原 base case 尾部的逐字搬运)
template<bool Right_>
static inline void leaf_emit(const U *T,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<4096;i+=32){
   __m256i a=ld(T+i),b=ld(T+4096+i),c=ld(T+8192+i),d=ld(T+12288+i);
   __m256i aa=ld(T+i+16),bb=ld(T+4096+i+16),cc=ld(T+8192+i+16),dd=ld(T+12288+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);
  }
}
template<bool Right_>
static void pack_leaf2(const U *s,int offset,U *dest,U *destq,int voff){
  constexpr int q=64*64+(64/BASE)*(64/BASE)*TILE_PAD;
  const int toff[4]={0,2048,2048*4096,2048*4096+2048};
  U *T=root_tile;
  for(int band=0;band<2;band++){
    const U *sA=s+(size_t)band*64*4096, *sB=sA+64;
    bool trA=pk_tr(sA), trB=pk_tr(sB);
    for(int t=0;t<4;t++){
      U *dA=T+t*4096,*dB=T+16384+t*4096;
      if(!Right_){
        if(S4BQ_FUSED){for(int i=0;i<64;i+=4){
          pk_rows_l(dA+(i/4)*256,sA+toff[t],i,64,4096,trA);
          pk_rows_l(dB+(i/4)*256,sB+toff[t],i,64,4096,trB);}}
        else{for(int i=0;i<64;i+=4) pk_rows_l(dA+(i/4)*256,sA+toff[t],i,64,4096,trA);
             for(int i=0;i<64;i+=4) pk_rows_l(dB+(i/4)*256,sB+toff[t],i,64,4096,trB);}
      }else{
        if(S4BQ_FUSED){for(int k=0;k<64;k+=2){
          pk_rows_r(dA,sA+toff[t],k,64,4096,trA);
          pk_rows_r(dB,sB+toff[t],k,64,4096,trB);}}
        else{for(int k=0;k<64;k+=2) pk_rows_r(dA,sA+toff[t],k,64,4096,trA);
             for(int k=0;k<64;k+=2) pk_rows_r(dB,sB+toff[t],k,64,4096,trB);}
      }
    }
    leaf_emit<Right_>(T,offset+(size_t)band*2*q,dest,destq,voff);
    leaf_emit<Right_>(T+16384,offset+(size_t)band*2*q+q,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){return pack_leaf2<Right>(s,offset,dest,destq,voff);}
 if(n>64){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(root_tile,s,64,4096,Right);
  pack(root_tile+4096,s+2048,64,4096,Right);
  pack(root_tile+8192,s+2048*4096,64,4096,Right);
  pack(root_tile+12288,s+2048*4096+2048,64,4096,Right);
  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<4096;i+=32){
   __m256i a=ld(root_tile+i),b=ld(root_tile+4096+i),c=ld(root_tile+8192+i),d=ld(root_tile+12288+i);
   __m256i aa=ld(root_tile+i+16),bb=ld(root_tile+4096+i+16),cc=ld(root_tile+8192+i+16),dd=ld(root_tile+12288+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);
  }
 }
}
template<int N,bool Inverse>
static __attribute__((noinline)) void partial_basis(U *a) {
 if constexpr(N>BASE) {
  constexpr int h=N/2,q=h*h+(h/BASE)*(h/BASE)*TILE_PAD;
  if constexpr(Inverse && N<=ALTMAX) {
   for(int chunk=0;chunk<q;chunk+=4096+TILE_PAD) for(int i=chunk;i<chunk+4096;i+=16) {
    __m256i x=ld(a+q+i),y=ld(a+2*q+i),z=ld(a+3*q+i);
    st(a+q+i,_mm256_sub_epi16(x,z));
    st(a+2*q+i,_mm256_sub_epi16(z,y));
   }
  }
  partial_basis<h,Inverse>(a);partial_basis<h,Inverse>(a+q);
  partial_basis<h,Inverse>(a+2*q);partial_basis<h,Inverse>(a+3*q);
  if constexpr(!Inverse && N<=ALTMAX) {
   for(int chunk=0;chunk<q;chunk+=4096+TILE_PAD) for(int i=chunk;i<chunk+4096;i+=16)
    st(a+3*q+i,_mm256_add_epi16(_mm256_sub_epi16(ld(a+q+i),ld(a+2*q+i)),ld(a+3*q+i)));
  }
 }
}

void matrix_multiply(int n,const short*A,const short*B,short*C){
 U *cq=(U*)C;                      // 借调用方 C 区(题面: 非 const、启动初值 0)作 3 个纯输入根槽
 U *ar=root_mem,*br=ar+4*RS,*pr=br+7*RS;   // root_mem 15 -> 12 槽
 raw_basis_input=(const U*)A;
 U *work=cq+3*RS+928;
 pack_root<false>((const U*)A,2048,0,ar,cq,0);
 raw_basis_input=(const U*)B;
 pack_root<true>((const U*)B,2048,0,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();
}


CompilationN/AN/ACompile OKScore: N/A

Testcase #1546.533 ms129 MB + 600 KBAcceptedScore: 100


Judge Duck Online | 评测鸭在线
Server Time: 2026-11-05 02:26:09 | Loaded in 2 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠