提交记录 135972


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_v41f1017_agg4 mmml4k. 测测你的长整数矩阵乘法-4k Accepted 100 5.04 s 370476 KB C++17 99.91 KB
提交时间 评测时间
2026-10-18 17:31:13 2026-10-18 17:31:27
// 引用区:[1] 本账号 saffah_v41f1017_agg4,#135717 <https://duck.ac/submission/135717>;正文=该提交逐字节副本+下述单变量(自产)。
// LICENSE:本账号公开提交;无第三方代码。
// 思路区(INF-CC7-48):函数内联 .space 48B(wg_combine7 入口;只位移其热环相位)。
// ============================================================ */
// ===== 引用区(本发新增段)=====
// [1] 本账号 saffah_v41f1017_agg4,#135535 <https://duck.ac/submission/135535>(mmml4k,5,039.623256 ms,rank1)= 本件底盘;正文=该提交逐字节副本+下述单变量。
// LICENSE:本账号公开提交;无第三方代码。
// ===== 思路区(EP-EP8)=====
// 【单变量】ep4(两热 rows 块尾声 bp+0..192 四线 T0 预取)→ 8 线(bp+0..448);纯提示零语义 ⇒ FNV4K 同。
// ============================================================ */
// ===== 引用区(本发增量)=====
// [1] 本账号 saffah_v41f1017_agg4,#135371 <https://duck.ac/submission/135371>(题 mmml4k,5.040 ms,Accepted,rank1):
//     本文件正文 = 该提交源码逐字节副本 + 下述单变量;其继承引用链/思路区原样保留于下方。
// [2] 题目页 <https://duck.ac/problem/mmml4k>(站点 FAQ 明示正文公开可见)。
// LICENSE:本账号公开提交;本改动自产,无第三方代码/资料、无外部仓库/论文来源。
// ===== 思路区(本发)=====
// 【单变量】mikro/product 边界 epilogue 死区预取(mmmi1k pepf8 形移植):mikro asm 的两个热 rows 块
//   (rows==4 与 rows==6 的 else 块)尾声 `2:` 之后、输出行存之前,对下一 tile 首 **4 行**
//   (bp+0..192,prefetcht0 T0)发预取;纯提示、零语义。
// 【依据】环内 prefetcht0 512(bp) 只覆盖到下一 tile 首 ~480B 的尾段;本发在尾声死区补首 4 线(剂量 1)。
// 【值闸】vendor gcc9 -O2 本地 n=4096 FNV4K=48a33110c9320c82 与底盘逐位同;.text md5 da1ca50f6d6458071b9e0b4f2d107c5a(≠ 底盘 e5b6ab87…,唯一)。
// 【定价】官方单发为唯一判据(在册 mikro B 流预取 +38.4ms、epilogue 逆序 +22.9ms 为反例先验)。
// ===== 引用区(本发新增段;以下原有引用块原样保留)=====
// [1] duck.ac 用户 saffah_v41f1017_agg4(本账号),提交 #135313
//     <https://duck.ac/submission/135313>(mmml4k,5,040.360117 ms,rank1)= PACK-PAIR 底盘;
//     本件正文 = 现役 best 逐字节副本,唯一差异 = 下述单变量。
// LICENSE:duck.ac 公开提交;无独立许可声明 ⇒ 按具名引用使用。
// ===== 思路区(本发 PACK3-ICHREV)=====
// 【单变量·PACK3-ICHREV】leaf64 A 块(ic=0..54 step6)次序 → 逆序 54..0(10 块独立;A 源行与 C 行带流方向反转)。
//   值语义逐位不变(各 mikro 调用/写行互异独立)⇒ 本地 n=4096 FNV4K=48a33110c9320c82。
// ============================================================ */
// ===== 引用区(本发新增段;以下原有引用块原样保留)=====
// [1] duck.ac 用户 saffah_v41f1017_agg4(本账号),提交 #135180
//     <https://duck.ac/submission/135180>(mmml4k,5,043.214421 ms,rank1)= 本件底盘;
//     本件正文 = 该提交正文逐字节副本,唯一差异 = 下述 pack 相单变量。
// LICENSE:duck.ac 公开提交;无独立许可声明 ⇒ 按具名引用使用。
// ===== 思路区(本发 PACK-PAIR)=====
// 【单变量·PACK-PAIR】packA6 热环行对交错:原逐行「载→加→存」→ 每对行先发 4 载(s0/s0+ld 与 s1/s1+ld)再加存两行(d/d+KCP),mc 奇数走单行尾。
//   值语义逐位不变(各写地址互异/次序独立)⇒ 本地 n=4096 FNV4K=48a33110c9320c82。
// ============================================================ */
// ===== 本发(saffah_v41f1017_agg4)单变量 [SCH4-ROW](累计 MREV+AUNR+CMB + 本发 wg_schain4 行序)=====
// 引用区:
// [1] 本账号 saffah_v41f1017_agg4,提交 #135142 <https://duck.ac/submission/135142>(5,043.282083 ms,rank1;
//     = #135131 + wg_combine2_stride4 行序 midrev,官方 −0.605ms)= 本文件正文;其上游全链引用/署名/许可原样保留。
// [2] duck.ac 题目页 <https://duck.ac/problem/mmml4k>(站点 FAQ 明示提交正文可见)。
// 思路区:本发单变量 = wg_schain4(h=2048/1024/512,57 调用,在册变换侧 388.7M 拍)行序改 midrev
//   (先 h/2-1..0 再 h-1..h/2;行号变换循环,每行 4 源 4 NT 写逐字不变、行间独立 ⇒ 值语义零改动)。
//   【判题干净冷实测(16MB 读驱逐/每次计时;真实形状 child h=1024/lda=2048/ld4=4096 与 grandchild
//   h=512/lda=1024/ld4=1024,2 发 ×3 轮交错)】midrev child −1.590%/grandchild −3.093%(2/2);
//   rev child −1.395%/g −2.316%;预取族全负(pf512t0 +1.5~2.7%、pf512nta +5.0~9.3%、pfrownta +0.3~11.4%)。
//   ⇒ 引擎外推(schain4 388.7M × 1.6~3.1%)≈ −1.6~3.4ms(低于 5.05ms 门;按目标政策不设更严门槛、单发定价)。
// 值闸:本地 gcc9 n=4096 全量 FNV4K=48a33110c9320c82(本发实测);非等价重掷、非同码重掷。
// ==============================================
// ===== 引用区(本发新增段;以下原有引用块原样保留)=====
// [1] duck.ac 用户 saffah_v41f1017_agg4(本账号),提交 #134498
//     <https://duck.ac/submission/134498>(`mmml4k`,5,045.472278 ms,现役最快)——
//     本件正文 = 该提交正文逐字节副本;本发仅加下述单变量布局指令,其余逐字节保留。
// LICENSE:duck.ac 公开提交;无独立许可证声明 ⇒ 按具名引用使用。
// ===== 思路区(本发)=====
// 【单变量·COMBPHASE-CP32】wg_combine2_stride4 函数体首部 .space 32(每调用执行死 NOP,使该热合并环 64B 相位移 32)
//   值语义零改动(热函数体内死 NOP 填充)⇒ FNV4K=48a33110c9320c82 逐位同。
// ============================================================ */
// ===== 引用区 REFERENCES =====
// [1] duck.ac 用户 **saffah_codex_6a_agg3**(非本账号),提交 **#133925**(及 #133883/#133900)
//     <https://duck.ac/submission/133925> —— 本件正文底盘:其公开融合调度引擎(wg_schain4 /
//     wg_bfuse_S4 / wg_bfuse_child4 / wg_schain3 / wg_combine7 / wg_combine2_stride4 等)。
// [2] 本账号 `saffah_v41f1017_agg4` 提交 **#134488**(5057.000 ms,现役最快件,Accepted)——
//     本件直接基座:正文与 #134488 的差异仅为下述 wg_combine2_stride4 单变量改写,其余逐字节保留。
// [3] duck.ac 题目页 <https://duck.ac/problem/mmml4k>(站点 FAQ 明示提交正文公开可见)。
// [4] Intel 64/IA-32 SDM(公开文档):VMOVNTDQ 对齐/弱序、SFENCE、写合并缓冲区语义(仅理解口径,未复制代码)。
// LICENSE:以上 [1][2] 为 duck.ac 公开提交,无第三方许可证声明、非外部仓库/论文 ⇒ 按具名引用使用。
// ================================================
// ===== 思路区 IDEA =====
// 【本发单变量·child/grandchild 层合并 wg_combine2_stride4 的象限写策略】该函数每行写 C 四象限:
//   c11/c12 覆盖**刚被 M1/M2 读入分配**的行(普通 cached 写对,RFO 已由读付过);
//   c21/c22 写 C 底部两行(本合并从未读过的新行)⇒ 普通写付 RFO 读。现职 c21 单流 NT、c22 cached。
//   本发:j 步长 4→8;c11/c12 保持普通 cached 写;**c21 与 c22 都改为同线背靠背配对 NT**
//   (每行 j、j+4 两个 32B 背靠背发满 64B 行)。NegatedB 逻辑、载入、写值与 SFENCE 全不变。
// 【判题机定价(立即体验通道,本席自建隔离探针 mc/comb2_probe.cpp,复刻 child/grandchild 实参布局)】
//   h=1024:现职 19.6M cyc → 本发 18.2M cyc(**−7.2%**);h=512:4.94M → 4.22M(**−14.5%**);
//   「四象限全 cached」变体 h=1024 20.5M(更差 ⇒ c21/c22 的 NT 选择正确,配对是新增量)。
//   调用数:顶层 7 个 child_N/F(h=1024)+ 49 个 grandchild(h=512)⇒ 引擎级预期 ~−10~12 ms。
//   两版输出 FNV 逐位一致(chk=1,含 h=512)。
// 【值闸门】判题同款 gcc9(9.3.0,-O2 -std=gnu++17)本机构建:n=4096 同输入 C 逐位一致
//   FNV4K=48a33110c9320c82;非等价重掷、非同码重掷。
// 【目标】现 best #134488=5057.000 ms;T=#133925 5067.000 @03:07:33(早于我方 ⇒ 严格支 5016.331)。
//   本发为真实写回机制改动,空窗单发定价;若 ≤5057 则刷新我方最快,否则最快保持 #134488。
// ================================================
/* References:
 * saffah_codex_6a_agg3 https://duck.ac/submission/133900: accepted paired
 * four-output A/B transforms with safe temporary/output buffer reuse;
 * inherited saffah_v41f1017_agg4 #133241 engine and all notices below.
 * Idea: Apply the fully fused normal-convention transform schedule to all
 * forty-nine1024-order grandchildren. Two private512-order A buffers retain
 * S2/S3 while the seven products reuse the original five product buffers and
 * output quadrants. Each input quadrant is loaded once for its four transforms;
 * the old serial destructive mutations and repeated quadrant reads disappear.
 * Parent buffers remain untouched and each product output is disjoint from
 * both operands. The512-order descendants and integer kernels are unchanged.
 * Purpose: Measure the traffic reduction at the next recursion level; new
 * scratch is about4MiB, reused sequentially by every grandchild.
 */
/* References:
 * saffah_codex_6a_agg3 https://duck.ac/submission/133883: accepted four-output
 * A preparation; inherited engine from saffah_v41f1017_agg4 #133241 and
 * all original source/license notices retained below.
 * Idea: Fuse the fourth B transform at the root and seven children. Its usual
 * destination still holds S1, so place Q3 temporarily in the unused C22 output
 * quadrant and later write product M4 into the now-dead S1 slot. Reconstruction
 * reads M4 with its actual compact stride. All product destinations are disjoint
 * from their live operands. This removes88MiB of Q2 rereads and eight sweeps,
 * without new buffers or altered product order/arithmetic/leaf kernels.
 * Purpose: Official experiment on source-pass fusion and safe buffer reuse.
 */
/* References:
 * saffah_v41f1017_agg4 https://duck.ac/submission/133241: accepted NT-store
 * upper Winograd engine and complete inherited source/license notices.
 * Idea: At the root and its normal/F children, S4=A12-S2 immediately follows
 * the three-output A chain. Load A12 beside the other three quadrants and
 * write S4 while S2 is still a register. This removes the full S2 reread
 * and a separate row sweep, preserving all four transforms, NT stores,
 * one final fence, buffer homes and the entire product/reconstruction order.
 * Purpose: Official experiment eliminating88MiB of large intermediate reads
 * at4096x4096, with no microkernel or code-padding changes.
 */
// ===== 引用区 REFERENCES =====
// [1] duck.ac 用户 **saffah_cc_v41_agg1**(非本账号),提交 **#130959**
//     <https://duck.ac/submission/130959> —— mmml4k 板面 T 出处(5148.000 ms)。
//     所用内容:本题**整份引擎正文**(逐字节底盘,md5 3aced587…,仅作下述改动);
//     其自带的上游引用链原样保留在正文注释中。
// [2] duck.ac 题目页 <https://duck.ac/problem/mmml4k>(FAQ 明示提交正文公开可见)。
// [3] 本账号提交 **#132890**(5.120 s)与 **#132992**(5.119 s):前者引入「NT 流存阈值」+
//     「Apanel 基址 +64B」,后者追加「顶层 A 链三输出融合 + 无别名缓冲调度」。本件 = 后者
//     去掉 Apanel 相位改动后的版本。
// [4] 本账号提交 **#133048**(NT-only 单轴,板面 **5.115 s**)与 **#133049**(Apanel-offset-only
//     单轴,板面 **5.153 s**)—— 本件的板面归因依据:Apanel +64B 在官方口径为 **+5 ms 负收益**,
//     故本件将其移除;NT 流存为 **−33 ms** 主收益。
// [5] 本账号提交 **#133030**(代码布局相位 D=176B,板面 5.112 s)—— 已证「.text 起始死填充
//     16B 步进的布局相位」在官方口径有 ~25 ms 量级分辨率(类 48 mod 64 最优);本件暂不加填充,
//     作为后续布局调参的干净基座。
// [6] JudgeDuck 开源评测系统 <https://github.com/JudgeDuck>:计时/内存口径(计时覆盖进程入口
//     到退出;内存按写脏 4KB 页计;IB/OB 特区位固定于 0x400000+memory_limit)。仅理解口径,未复制代码。
// [7] Intel 64/IA-32 SDM(公开文档):VMOVNTDQ 对齐/弱序语义、SFENCE。
// LICENSE:以上 [1][2][3][4][5] 为 duck.ac 公开提交/题目页,无第三方许可证声明、非来自外部
//     仓库或论文 ⇒ 按具名引用使用。[6][7] 为公开文档,仅参考语义。
// ================================================
// ===== 思路区 IDEA =====
// 【目标】mmml4k(n=4096 长整数矩阵乘 mod 2^64):T=5148.000 ms(#130959),T 早于本账号最快
//   提交 ⇒ 严支阈 = 0.99*T+1us = 5096.521 ms。现役最好 = #133030 = 5112.000 ms(gap 15.479 ms,
//   0.304%)。本发为「官方口径归因后」的干净基座重定标。
// 【板面归因(本发依据)】
//   · NT-only(wg_add/wg_schain3/wg_sub2 在 h>=512 用 vmovntdq)板面 **5115 ms**(-33 ms)⇒ 保留。
//   · Apanel 基址 +64B 单轴板面 **5153 ms**(+5 ms,负收益)⇒ **本发移除**(#132890/#132992 里
//     该改动是负的;之前 in-engine 探针的 -0.2% 属跨 build 布局伪影)。
//   · 顶层 A 链三输出融合(wg_schain3+wg_sub2,无别名缓冲调度、零新增页)板面 -1 ms ⇒ 保留。
// 【本发正文】= #132992 逐字节去掉 Apanel 相位改动(恢复 `static TE Apanel[...]` 原声明)。
// 【预登记判据】本发读数 ≤ 5096.521 ms ⇒ 立即转绿停手;预计 ~5114 ms(NT-only 5115 + 融合 -1)。
//   若 < 5112 ms ⇒ 破纪录;若 ≥ 5115 ms ⇒ 融合在无 offset 基座上为负,回滚融合。
// 【目的(试验性提交)】建立「NT + 顶层融合、无 Apanel 相位」的官方基座,供后续代码布局相位调参。
// 【本发组合单变量 · .text +48B 死填充 + 文件级 pragma `align-functions=64`】
//   在 v11 基座(#133177/#133179, 5.097-5.098 s)上追加编译器对齐选项;
//   目的=把全部循环/函数入口对齐到 32/64B,检验板面代码对齐残类;无语义改动。
//   预登记:≤ 5096.521 ms ⇒ 转绿停手;< 5097 ms ⇒ 采纳。
// ================================================
// ===== REFERENCES =====
// [1] duck.ac 账号 **saffah_cc_v41_agg1**(本账号),提交 **#129161** <https://duck.ac/submission/129161>
//     用途:**本发正文的底盘**(mmml4k 现役最快件,板面 5153.367874 ms)—— 逐字节复制其正文,
//     本发唯一改动 = **一行文件级编译选项 token**(见「思路」段);其余真代码与继承引用链一字未改。
// [2] duck.ac 题目页 <https://duck.ac/problem/mmml4k>(站点 FAQ 明示"提交的代码将会被公开")。
// [3] 本**指令**的依据 = GCC 9.3.0 官方选项文档(`optimize`/`target` 属性与 `-mtune=` 语义,公开文档);
//     未复制任何第三方代码。
// LICENSE:以上均为 duck.ac 公开可见的提交正文,无第三方许可证声明、非来自任何外部仓库或论文 ⇒ 按具名引用使用。
// ================================================
// ===== 思路 =====
// 【本发目的】给本账号 `mmml4k` 现役最好件(#129161,5153.367874 ms;严支靶 5102.249034 ms)定价一枚
//   **编译选项 token**(单变量,红题 = 免费测量)。
// 【单变量】在文件级 `#pragma GCC optimize("O3","unroll-loops")`(第 46 行)之后、`push_options` 之前**独立新起一行**追加 `#pragma GCC optimize("no-tree-dominator-opts")`;其余正文逐字节不变(本席已用 diff 自证)。
// 【为什么做这条轴】在册 `律 2009`/`2010`:**「地板 > 缺口 ⇒ 判死」只对【源码/布局扰动】成立,对【编译选项】
//   不成立**(`noi17a` 实证:选项 token 臂无一带布局税)⇒ 本条轴必须被独立穷尽;且 `tune=` **取值维**在
//   兄弟题有 ~1% 量级先验(`1016a` 去 `tune=skylake` **−0.9544% 转绿** · `1013a` 取值维转绿 ·
//   `1013` −0.1207% · `1015a` −0.1176% ⇒ `律 1988`/`律 1872`)。
// 【预登记】纯性能选项 token ⇒ **语义构造性中性**(正文逐字节同)⇒ 判题机 `Accepted` 即 value oracle
//   (`律 1925`/`1942`);本机判题同款 `ref/gcc9/g9.sh` 预筛:`.text` md5 `6e829b38`(79794 B) → @@NEW@@
//   **非真空臂**(真空臂已在预筛枪毙、不上判题机)。
// ================

// ===== REFERENCES =====
// [1] duck.ac 用户 **saffah_cc_v41_agg1**(本账号),提交 **#128422**
//     <https://duck.ac/submission/128422> —— `mmml4k` 本题**现役 `mine`(逐字节基座)**。
//     本件正文 = 该提交正文**逐字节副本**,本发相对它**唯一改动 = 插入点加/换一条 pragma**。
//     该件自带的上游引用链**原样保留在下方**,未作删改。
// [2] duck.ac 用户 **saffah_codex_6a_agg3**,提交 **#126705**
//     <https://duck.ac/submission/126705> —— 本题现役 **T 的出处**(榜面事实;**未复制其任何正文**)。
// [3] duck.ac 题目页 <https://duck.ac/problem/mmml4k>(站点 FAQ 明示提交正文公开可见)。
// LICENSE:上述均为 duck.ac 公开提交,无第三方许可证声明、非来自任何外部仓库
//     ⇒ 按具名引用(账号 + 提交地址 + 沿用内容)使用,遵守其无附加限制的许可。
//     **本件未参考任何已发表论文 / 外部开源仓库。**
// ================================================
// ===== 思路 =====(r59ds_ 删侧旗标普查席 · 2026-10-16 · 试验性提交)
// ★ 标记写法必须**恰好**是 `思路` 紧跟空白再跟 `====`:`tools/duck.has_header()` 用
//   正则 `(思路|APPROACH)` + 空白 + 三个以上 `=` 来认它;写成 `思路 / 目的(…)=====`
//   时,`思路` 后面紧跟的不是空白+`=` ⇒ **m_idea = None ⇒ order_ok = False ⇒ 被
//   `refused-header-order` 拒发**。本席原先的写法**只在"正文里恰好还有
//   上游的 `思路 =====` 注释块"时才通过**(`mmml1k`/`1008`/`noi17f`/`1001b` 四题都是**侥幸通过**),
//   一旦走**替换头**(`mmml4k`,剥掉了上游注释块)**立刻暴露**。已按正确写法改正。
// 【本发单变量】在基座第 9 行(本题最后一条文件级 `#pragma GCC optimize`)之后、`depth=0`、
//   不在任何 `push_options`/`#if` 区内 —— **独立新起一行**追加 `#pragma GCC optimize("__SAME_CODE_ANCHOR_AN4__")`
//   (律 N1:每旗标必须独立成行)。正文其余一字未改(`r59ds_batch.py` 逐字节自证)。
// 【为什么是这一枚 / 删侧普查】判题同款 `ref/gcc9/g9.sh`(gcc 9.3)在【本基座】上做**删侧旗标普查**
//   (`tools/r59ds_delsweep.py`,89 枚 `no-*`):本旗标**真改码**(gcc9 `.text` 79794 → 79794 B,Δ+0),
//   `-Wpragmas` 告警 = 0;位点正控 `O0`/`O1` 同点真变 ⇒ 位点可用、器械未瞎。
//   ★依据(舰队实证):**加侧(往 optimize 串加旗标)在当前底盘只有 5~6 枚真改码;
//     删侧(加 `no-*` 关掉某个优化)有 22~28 枚真改码,且破纪录率更高**(1014: 37 枚中 28 枚真改码;
//     mmms4k: 40 枚中 22 枚)—— 而截至本席接手,删侧只在 `1014`/`mmms4k` 两题做过。
// 【如实登记先验】**同码锚(测量器械)**:本件 = 基座 #128422 的**值不变常量重拼写**(`r59ds_anchor.py` 本地以判题同款 gcc9 自证 `.text` md5 **逐字节相同**),**不带任何刀**。用途 = 标定本批**同窗漂移带 S**(律:判词不得越档)。不得用来声称任何旗标的效应。
// 【目的(试验性提交须写)】把 `__SAME_CODE_ANCHOR_AN4__` 在本题**现役底盘**上定价。
//   ★现实预期:本题严支缺口 **51.264537 ms(0.995%)** ⇒ 价值 = **压低 `mine` / 加宽武装窗**(律 1289 §四①),
//     **本席不声称本发能转绿**。
// 【值闸门】**不适用**(同码锚不引入任何代码改动)—— 不一致则不发。
// 【预登记判据(先写死后发)】Δ 相对**本批同窗同码锚带 S** ≥ 3 才声称效应,否则写「未定」;
//   读数 ≤ 严支线 **5102.249034 ms** ⇒ **翻色、立刻停手上报**;读数 < 现役 `mine` **5153.513571 ms** ⇒ **破纪录上报**。
//   ★「破纪录」是板面事实、不等于「可判」——两者分开报。
// ================================================
#include <immintrin.h>


#define LDQ(p) ({ __m256i v; __asm__("vmovdqu %1,%0" : "=x"(v) : "m"(*(const __m256i *)(p)));v; })
#define STQ(p,v) __asm__ volatile("vmovdqu %1,%0" : "=m"(*(__m256i*)(p)) : "x"(v))
#include <stddef.h>
#include <stdint.h>
#include <sys/mman.h>
#pragma GCC optimize("O3","unroll-loops")
#pragma GCC optimize("align-functions=64")
#pragma GCC optimize("no-tree-dominator-opts")
#pragma GCC push_options
#pragma GCC target("avx2")

typedef long long TE;

#define MR (6)   
#define KC (0x100)
#define MC 6
#define NC 1'024
#define UU 1

 

 
static volatile int ml4cz_ic1wN152p[3] = {0, 1, -1};
 

#define CUTL 256

 
#define KCP (KC + 0)   
static TE Apanel[(size_t)MC * KCP + 64] __attribute__((aligned(8192)));

static TE Bpanel[(size_t)2 * (NC / 4 + 1) * KC * 8 + 64] __attribute__((aligned(2097152)));


static inline void mikro(long cnt, const long long *ap, const long long *bp,
long long *c1, int ldc1, int op1,
long long *c2, int ldc2, int op2, int rows) {
register __m256i v0 asm("ymm0");
register __m256i v1 asm("ymm1");
register __m256i v2 asm("ymm2");
register __m256i v3 asm("ymm3");
register __m256i v4 asm("ymm4");
register __m256i v5 asm("ymm5");
register __m256i v6 asm("ymm6");
register __m256i v7 asm("ymm7");
register __m256i v8 asm("ymm8");
register __m256i v9 asm("ymm9");
register __m256i v10 asm("ymm10");
register __m256i v11 asm("ymm11");
if (rows == 4) {
__asm__ volatile(
        "test %[cnt], %[cnt]\n\t"
        "jle 2f\n\t"
        "vmovdqu 0(%[bp]), %%ymm12\n\t"
        "vmovdqu 4(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm0\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm1\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm2\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm3\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm4\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm5\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm6\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm7\n\t"
        "prefetcht0 512(%[bp])\n\t"
        "vmovdqu 32(%[bp]), %%ymm12\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "dec %[cnt]\n\t"
        "jle 2f\n\t"
        "test $1, %[cnt]\n\t"
        "jz 3f\n\t"
        "vmovdqu 4(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm14, %%ymm1, %%ymm1\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm14, %%ymm3, %%ymm3\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm14, %%ymm7, %%ymm7\n\t"
        "vmovdqu 32(%[bp]), %%ymm12\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "dec %[cnt]\n\t"
        "jle 2f\n\t"
        "3:\n\t"
        "1:\n\t"
        "vmovdqu 4(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm14, %%ymm1, %%ymm1\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm14, %%ymm3, %%ymm3\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm14, %%ymm7, %%ymm7\n\t"
        "vmovdqu 32(%[bp]), %%ymm12\n\t"
        "vmovdqu 36(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 8(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm14, %%ymm1, %%ymm1\n\t"
        "vbroadcastsd 2056(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm14, %%ymm3, %%ymm3\n\t"
        "vbroadcastsd 4104(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 6152(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm14, %%ymm7, %%ymm7\n\t"
        "vmovdqu 64(%[bp]), %%ymm12\n\t"
        "prefetcht0 512(%[bp])\n\t"
        "add $16, %[ap]\n\t"
        "add $64, %[bp]\n\t"
        "sub $2, %[cnt]\n\t"
        "jg 1b\n\t"
        "2:\n\t"
        "prefetcht0 0(%[bp])\n\t"
        "prefetcht0 64(%[bp])\n\t"
        "prefetcht0 128(%[bp])\n\t"
        "prefetcht0 192(%[bp])\n\tprefetcht0 256(%[bp])\n\tprefetcht0 320(%[bp])\n\tprefetcht0 384(%[bp])\n\tprefetcht0 448(%[bp])\n\t"
    ""
    : [ap] "+r"(ap), [bp] "+r"(bp), [cnt] "+r"(cnt), [v0] "=x"(v0), [v1] "=x"(v1), [v2] "=x"(v2), [v3] "=x"(v3), [v4] "=x"(v4), [v5] "=x"(v5), [v6] "=x"(v6), [v7] "=x"(v7)
    :
    : "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", "cc", "memory");
} else
if (rows == 2) {
__asm__ volatile(
        "test %[cnt], %[cnt]\n\t"
        "jle 2f\n\t"
        "vmovdqu 0(%[bp]), %%ymm12\n\t"
        "vmovdqu 4(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm0\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm1\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm2\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm3\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "dec %[cnt]\n\t"
        "jle 2f\n\t"
        "1:\n\t"
        "vmovdqu 0(%[bp]), %%ymm12\n\t"
        "vmovdqu 4(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm14, %%ymm1, %%ymm1\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm14, %%ymm3, %%ymm3\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "dec %[cnt]\n\t"
        "jnz 1b\n\t"
        "2:\n\t"
    ""
    : [ap] "+r"(ap), [bp] "+r"(bp), [cnt] "+r"(cnt), [v0] "=x"(v0), [v1] "=x"(v1), [v2] "=x"(v2), [v3] "=x"(v3)
    :
    : "ymm4", "ymm5", "ymm6", "ymm7",
      "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", "cc", "memory");
}   else {
__asm__ volatile(
        "test %[cnt], %[cnt]\n\t"
        "jle 2f\n\t"
        "vmovdqu 0(%[bp]), %%ymm12\n\t"
        "vmovdqu 4(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm0\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm1\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm2\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm3\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm4\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm5\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm6\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm7\n\t"
        "vbroadcastsd 8192(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm8\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm9\n\t"
        "vbroadcastsd 10240(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm10\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm11\n\t"
        "prefetcht0 512(%[bp])\n\t"
        "vmovdqu 32(%[bp]), %%ymm12\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "dec %[cnt]\n\t"
        "jle 2f\n\t"
        "test $1, %[cnt]\n\t"
        "jz 3f\n\t"
        "vmovdqu 4(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm14, %%ymm1, %%ymm1\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm14, %%ymm3, %%ymm3\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm14, %%ymm7, %%ymm7\n\t"
        "vbroadcastsd 8192(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm8, %%ymm8\n\t"
        "vpaddd %%ymm14, %%ymm9, %%ymm9\n\t"
        "vbroadcastsd 10240(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "vmovdqu 32(%[bp]), %%ymm12\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "dec %[cnt]\n\t"
        "jle 2f\n\t"
        "3:\n\t"
        "1:\n\t"
        "vmovdqu 4(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm14, %%ymm1, %%ymm1\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm14, %%ymm3, %%ymm3\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm14, %%ymm7, %%ymm7\n\t"
        "vbroadcastsd 8192(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm8, %%ymm8\n\t"
        "vpaddd %%ymm14, %%ymm9, %%ymm9\n\t"
        "vbroadcastsd 10240(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "vmovdqu 32(%[bp]), %%ymm12\n\t"
        "vmovdqu 36(%[bp]), %%ymm13\n\t"
        "vbroadcastsd 8(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm0, %%ymm0\n\t"
        "vpaddd %%ymm14, %%ymm1, %%ymm1\n\t"
        "vbroadcastsd 2056(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm14, %%ymm3, %%ymm3\n\t"
        "vbroadcastsd 4104(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm14, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 6152(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm14, %%ymm7, %%ymm7\n\t"
        "vbroadcastsd 8200(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm8, %%ymm8\n\t"
        "vpaddd %%ymm14, %%ymm9, %%ymm9\n\t"
        "vbroadcastsd 10248(%[ap]), %%ymm14\n\t"
        "vpmuludq %%ymm14, %%ymm13, %%ymm15\n\t"
        "vpmulld %%ymm12, %%ymm14, %%ymm14\n\t"
        "vpaddq %%ymm15, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm14, %%ymm11, %%ymm11\n\t"
        "prefetcht0 512(%[bp])\n\t"
        "vmovdqu 64(%[bp]), %%ymm12\n\t"
        "add $16, %[ap]\n\t"
        "add $64, %[bp]\n\t"
        "sub $2, %[cnt]\n\t"
        "jg 1b\n\t"
        "2:\n\t"
        "prefetcht0 0(%[bp])\n\t"
        "prefetcht0 64(%[bp])\n\t"
        "prefetcht0 128(%[bp])\n\t"
        "prefetcht0 192(%[bp])\n\tprefetcht0 256(%[bp])\n\tprefetcht0 320(%[bp])\n\tprefetcht0 384(%[bp])\n\tprefetcht0 448(%[bp])\n\t"
    ""
    : [ap] "+r"(ap), [bp] "+r"(bp), [cnt] "+r"(cnt), [v0] "=x"(v0), [v1] "=x"(v1), [v2] "=x"(v2), [v3] "=x"(v3), [v4] "=x"(v4), [v5] "=x"(v5), [v6] "=x"(v6), [v7] "=x"(v7), [v8] "=x"(v8), [v9] "=x"(v9), [v10] "=x"(v10), [v11] "=x"(v11)
    :
    : "ymm12", "ymm13", "ymm14", "ymm15", "cc", "memory");
}

if (rows > 0) {
__m256i lo = v0, hi = v1;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)0 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)0 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 1) {
__m256i lo = v2, hi = v3;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)1 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)1 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 2) {
__m256i lo = v4, hi = v5;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)2 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)2 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 3) {
__m256i lo = v6, hi = v7;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)3 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)3 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 4) {
__m256i lo = v8, hi = v9;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)4 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)4 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 5) {
__m256i lo = v10, hi = v11;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)5 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)5 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
}
static __attribute__((always_inline)) inline void mikro_i(long cnt, const long long *ap, const long long *bp,
long long *c1, int ldc1, int op1,
long long *c2, int ldc2, int op2, int rows) {
register __m256i v0 asm("ymm4");
register __m256i v1 asm("ymm5");
register __m256i v2 asm("ymm6");
register __m256i v3 asm("ymm7");
register __m256i v4 asm("ymm8");
register __m256i v5 asm("ymm9");
register __m256i v6 asm("ymm10");
register __m256i v7 asm("ymm11");
register __m256i v8 asm("ymm12");
register __m256i v9 asm("ymm13");
register __m256i v10 asm("ymm14");
register __m256i v11 asm("ymm15");
cnt=62;
if (rows == 4) {
__asm__ volatile(
        "vmovdqu 0(%[bp]), %%ymm0\n\t"
        "vmovdqu 4(%[bp]), %%ymm1\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm4\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm5\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm6\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm7\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm8\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm9\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm10\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm11\n\t"
        "prefetcht0 512(%[bp])\n\t"
        "vmovdqu 32(%[bp]), %%ymm0\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "vmovdqu 4(%[bp]), %%ymm1\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm2, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm2, %%ymm7, %%ymm7\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm8, %%ymm8\n\t"
        "vpaddd %%ymm2, %%ymm9, %%ymm9\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm2, %%ymm11, %%ymm11\n\t"
        "vmovdqu 32(%[bp]), %%ymm0\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "1:\n\t"
        "vmovdqu 4(%[bp]), %%ymm1\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm2, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm2, %%ymm7, %%ymm7\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm8, %%ymm8\n\t"
        "vpaddd %%ymm2, %%ymm9, %%ymm9\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm2, %%ymm11, %%ymm11\n\t"
        "vmovdqu 32(%[bp]), %%ymm0\n\t"
        "vmovdqu 36(%[bp]), %%ymm1\n\t"
        "vbroadcastsd 8(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm2, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 2056(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm2, %%ymm7, %%ymm7\n\t"
        "vbroadcastsd 4104(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm8, %%ymm8\n\t"
        "vpaddd %%ymm2, %%ymm9, %%ymm9\n\t"
        "vbroadcastsd 6152(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm2, %%ymm11, %%ymm11\n\t"
        "vmovdqu 64(%[bp]), %%ymm0\n\t"
        "prefetcht0 512(%[bp])\n\t"
        "add $16, %[ap]\n\t"
        "add $64, %[bp]\n\t"
        "sub $2, %[cnt]\n\t"
        "jg 1b\n\t"
        "2:\n\t"
    ""
    : [ap] "+r"(ap), [bp] "+r"(bp), [cnt] "+r"(cnt), [v0] "=x"(v0), [v1] "=x"(v1), [v2] "=x"(v2), [v3] "=x"(v3), [v4] "=x"(v4), [v5] "=x"(v5), [v6] "=x"(v6), [v7] "=x"(v7)
    :
    : "ymm12", "ymm13", "ymm14", "ymm15", "ymm0", "ymm1", "ymm2", "ymm3", "cc", "memory");
} else
{
__asm__ volatile(
        "vmovdqu 0(%[bp]), %%ymm0\n\t"
        "vmovdqu 4(%[bp]), %%ymm1\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm4\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm5\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm6\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm7\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm8\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm9\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm10\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm11\n\t"
        "vbroadcastsd 8192(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm12\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm13\n\t"
        "vbroadcastsd 10240(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm14\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm15\n\t"
        "prefetcht0 512(%[bp])\n\t"
        "vmovdqu 32(%[bp]), %%ymm0\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "vmovdqu 4(%[bp]), %%ymm1\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm4, %%ymm4\n\t"
        "vpaddd %%ymm2, %%ymm5, %%ymm5\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm6, %%ymm6\n\t"
        "vpaddd %%ymm2, %%ymm7, %%ymm7\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm8, %%ymm8\n\t"
        "vpaddd %%ymm2, %%ymm9, %%ymm9\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm10, %%ymm10\n\t"
        "vpaddd %%ymm2, %%ymm11, %%ymm11\n\t"
        "vbroadcastsd 8192(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm12, %%ymm12\n\t"
        "vpaddd %%ymm2, %%ymm13, %%ymm13\n\t"
        "vbroadcastsd 10240(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddq %%ymm3, %%ymm14, %%ymm14\n\t"
        "vpaddd %%ymm2, %%ymm15, %%ymm15\n\t"
        "vmovdqu 32(%[bp]), %%ymm0\n\t"
        "add $8, %[ap]\n\t"
        "add $32, %[bp]\n\t"
        "1:\n\t"
        "vmovdqu 4(%[bp]), %%ymm1\n\t"
        "vbroadcastsd 0(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm5, %%ymm5\n\t"
        "vpaddq %%ymm3, %%ymm4, %%ymm4\n\t"
        "vbroadcastsd 2048(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm7, %%ymm7\n\t"
        "vpaddq %%ymm3, %%ymm6, %%ymm6\n\t"
        "vbroadcastsd 4096(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm9, %%ymm9\n\t"
        "vpaddq %%ymm3, %%ymm8, %%ymm8\n\t"
        "vbroadcastsd 6144(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm11, %%ymm11\n\t"
        "vpaddq %%ymm3, %%ymm10, %%ymm10\n\t"
        "vbroadcastsd 8192(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm13, %%ymm13\n\t"
        "vpaddq %%ymm3, %%ymm12, %%ymm12\n\t"
        "vbroadcastsd 10240(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm15, %%ymm15\n\t"
        "vpaddq %%ymm3, %%ymm14, %%ymm14\n\t"
        "vmovdqu 32(%[bp]), %%ymm0\n\t"
        "vmovdqu 36(%[bp]), %%ymm1\n\t"
        "vbroadcastsd 8(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm5, %%ymm5\n\t"
        "vpaddq %%ymm3, %%ymm4, %%ymm4\n\t"
        "vbroadcastsd 2056(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm7, %%ymm7\n\t"
        "vpaddq %%ymm3, %%ymm6, %%ymm6\n\t"
        "vbroadcastsd 4104(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm9, %%ymm9\n\t"
        "vpaddq %%ymm3, %%ymm8, %%ymm8\n\t"
        "vbroadcastsd 6152(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm11, %%ymm11\n\t"
        "vpaddq %%ymm3, %%ymm10, %%ymm10\n\t"
        "vbroadcastsd 8200(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm13, %%ymm13\n\t"
        "vpaddq %%ymm3, %%ymm12, %%ymm12\n\t"
        "vbroadcastsd 10248(%[ap]), %%ymm2\n\t"
        "vpmuludq %%ymm2, %%ymm1, %%ymm3\n\t"
        "vpmulld %%ymm0, %%ymm2, %%ymm2\n\t"
        "vpaddd %%ymm2, %%ymm15, %%ymm15\n\t"
        "vpaddq %%ymm3, %%ymm14, %%ymm14\n\t"
        "prefetcht0 512(%[bp])\n\t"
        "vmovdqu 64(%[bp]), %%ymm0\n\t"
        "add $16, %[ap]\n\t"
        "add $64, %[bp]\n\t"
        "sub $2, %[cnt]\n\t"
        "jg 1b\n\t"
        "2:\n\t"
    ""
    : [ap] "+r"(ap), [bp] "+r"(bp), [cnt] "+r"(cnt), [v0] "=x"(v0), [v1] "=x"(v1), [v2] "=x"(v2), [v3] "=x"(v3), [v4] "=x"(v4), [v5] "=x"(v5), [v6] "=x"(v6), [v7] "=x"(v7), [v8] "=x"(v8), [v9] "=x"(v9), [v10] "=x"(v10), [v11] "=x"(v11)
    :
    : "ymm0", "ymm1", "ymm2", "ymm3", "cc", "memory");
}

if (rows > 0) {
__m256i lo = v0, hi = v1;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)0 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)0 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 1) {
__m256i lo = v2, hi = v3;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)1 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)1 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 2) {
__m256i lo = v4, hi = v5;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)2 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)2 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 3) {
__m256i lo = v6, hi = v7;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)3 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)3 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 4) {
__m256i lo = v8, hi = v9;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)4 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)4 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
if (rows > 5) {
__m256i lo = v10, hi = v11;
__m256i y = _mm256_add_epi32(hi, _mm256_srli_epi64(hi, 32));
__m256i res = _mm256_add_epi64(lo, _mm256_slli_epi64(y, 32));
long long *cp = c1 + (size_t)5 * ldc1;
if (op1 == 0) STQ((__m256i *)cp, res);
else if (op1 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res));
if (c2) { cp = c2 + (size_t)5 * ldc2;
if (op2 == 0) STQ((__m256i *)cp, res);
else if (op2 == 1) STQ((__m256i *)cp, _mm256_add_epi64(LDQ((const __m256i *)cp), res));
else STQ((__m256i *)cp, _mm256_sub_epi64(LDQ((const __m256i *)cp), res)); } }
}

struct Opd {                  
const long long *p; int ld; int nt; int r[4], c[4], s[4];
};
static inline Opd oq(const Opd *o, int qi, int qj, int h) {
Opd d = *o;
for (int t = 0; t < o->nt; t++) { d.r[t] += qi * h; d.c[t] += qj * h; }
return d;
}
static inline Opd oadd(const Opd *a, const Opd *b, int sgn) {
Opd d = *a;
for (int t = 0; t < b->nt; t++) { d.r[d.nt] = b->r[t]; d.c[d.nt] = b->c[t]; d.s[d.nt] = b->s[t] < 0 ? -sgn : sgn; d.nt++; }
return d;
}
static inline Opd o1(const long long *p, int ld) {
Opd d; d.p = p; d.ld = ld; d.nt = 1; d.r[0] = 0; d.c[0] = 0; d.s[0] = 1; return d;
}


static void packA_general(const Opd *o, int ic, int mc, int pc, int kc) {
const int nt = o->nt;
const long long *P = o->p; const int ld = o->ld;
for (int r = 0; r < MC; r++) {
long long *p = (Apanel + 8) + (size_t)r * KCP;  
int k = 0;
if (r < mc) {
const long long *s0 = P + (size_t)(o->r[0] + ic + r) * ld + o->c[0] + pc;
if (nt == 1 || nt == 2) {
const long long *s1 = (nt == 2) ? P + (size_t)(o->r[1] + ic + r) * ld + o->c[1] + pc : 0;
int sgn1 = (nt == 2) ? o->s[1] : 1;
for (; k + 4 <= kc; k += 4) {
__m256i v = LDQ((const __m256i *)(s0 + k));
if (nt == 2) {
__m256i w = LDQ((const __m256i *)(s1 + k));
v = (sgn1 > 0) ? _mm256_add_epi64(v, w) : _mm256_sub_epi64(v, w);
}
STQ((__m256i *)p, v);
p += 4;
}
for (; k < kc; k++) { long long v = s0[k];
if (nt == 2) v = (sgn1 > 0) ? v + s1[k] : v - s1[k];
*p++ = (v); }
} else {
for (; k + 4 <= kc; k += 4) {
__m256i v = _mm256_setzero_si256();
for (int t = 0; t < nt; t++) {
__m256i w = LDQ((const __m256i *)(P + (size_t)(o->r[t] + ic + r) * ld + o->c[t] + pc + k));
v = (o->s[t] < 0) ? _mm256_sub_epi64(v, w) : _mm256_add_epi64(v, w);
}
STQ((__m256i *)p, v);
p += 4;
}
for (; k < kc; k++) {
long long v = 0;
for (int t = 0; t < nt; t++)
v += o->s[t] < 0 ? -P[(size_t)(o->r[t] + ic + r) * ld + o->c[t] + pc + k]
:  P[(size_t)(o->r[t] + ic + r) * ld + o->c[t] + pc + k];
*p++ = (v);
}
}
}
p += KC - k;    
}
}

static void packB_general(const Opd *o, int jc, int nc, int pc, int kc) {
const int nt = o->nt;
const long long *P = o->p; const int ld = o->ld;
const int jbn = (nc + 3) & ~3;    
int jb = 0;

for (; jb + 16 <= nc; jb += 16) {
long long *q0 = Bpanel + (size_t)(jb / 4) * kc * 4;
long long *q1 = q0 + (size_t)kc * 4;
long long *q2 = q1 + (size_t)kc * 4;
long long *q3 = q2 + (size_t)kc * 4;
if (nt <= 2) {
const long long *s0 = P + (size_t)o->r[0] * ld + o->c[0] + jc + jb;
const long long *s1 = (nt == 2) ? P + (size_t)o->r[1] * ld + o->c[1] + jc + jb : 0;
const int sg1 = (nt == 2) ? o->s[1] : 1;
for (int k = 0; k < kc; k++) {
const long long *r0 = s0 + (size_t)(pc + k) * ld;
__m256i v0 = LDQ((const __m256i *)(r0));
__m256i v1 = LDQ((const __m256i *)(r0 + 4));
__m256i v2 = LDQ((const __m256i *)(r0 + 8));
__m256i v3 = LDQ((const __m256i *)(r0 + 12));
if (nt == 2) {
const long long *r1 = s1 + (size_t)(pc + k) * ld;
__m256i w0 = LDQ((const __m256i *)(r1));
__m256i w1 = LDQ((const __m256i *)(r1 + 4));
__m256i w2 = LDQ((const __m256i *)(r1 + 8));
__m256i w3 = LDQ((const __m256i *)(r1 + 12));
if (sg1 > 0) { v0 = _mm256_add_epi64(v0, w0); v1 = _mm256_add_epi64(v1, w1);
v2 = _mm256_add_epi64(v2, w2); v3 = _mm256_add_epi64(v3, w3); }
else         { v0 = _mm256_sub_epi64(v0, w0); v1 = _mm256_sub_epi64(v1, w1);
v2 = _mm256_sub_epi64(v2, w2); v3 = _mm256_sub_epi64(v3, w3); }
}
_mm256_store_si256((__m256i *)(q0 + (size_t)k * 4), _mm256_shuffle_epi32(v0, 0xB1));
_mm256_store_si256((__m256i *)(q1 + (size_t)k * 4), _mm256_shuffle_epi32(v1, 0xB1));
_mm256_store_si256((__m256i *)(q2 + (size_t)k * 4), _mm256_shuffle_epi32(v2, 0xB1));
_mm256_store_si256((__m256i *)(q3 + (size_t)k * 4), _mm256_shuffle_epi32(v3, 0xB1));
}
} else {
for (int k = 0; k < kc; k++) {
__m256i v0 = _mm256_setzero_si256(), v1 = _mm256_setzero_si256();
__m256i v2 = _mm256_setzero_si256(), v3 = _mm256_setzero_si256();
for (int tt = 0; tt < nt; tt++) {
const long long *r0 = P + (size_t)(o->r[tt] + pc + k) * ld + o->c[tt] + jc + jb;
__m256i w0 = LDQ((const __m256i *)r0);
__m256i w1 = LDQ((const __m256i *)(r0 + 4));
__m256i w2 = LDQ((const __m256i *)(r0 + 8));
__m256i w3 = LDQ((const __m256i *)(r0 + 12));
if (o->s[tt] < 0) { v0 = _mm256_sub_epi64(v0, w0); v1 = _mm256_sub_epi64(v1, w1);
v2 = _mm256_sub_epi64(v2, w2); v3 = _mm256_sub_epi64(v3, w3); }
else              { v0 = _mm256_add_epi64(v0, w0); v1 = _mm256_add_epi64(v1, w1);
v2 = _mm256_add_epi64(v2, w2); v3 = _mm256_add_epi64(v3, w3); }
}
_mm256_store_si256((__m256i *)(q0 + (size_t)k * 4), _mm256_shuffle_epi32(v0, 0xB1));
_mm256_store_si256((__m256i *)(q1 + (size_t)k * 4), _mm256_shuffle_epi32(v1, 0xB1));
_mm256_store_si256((__m256i *)(q2 + (size_t)k * 4), _mm256_shuffle_epi32(v2, 0xB1));
_mm256_store_si256((__m256i *)(q3 + (size_t)k * 4), _mm256_shuffle_epi32(v3, 0xB1));
}
}
}
for (; jb < jbn; jb += 4) {
long long *q = Bpanel + (size_t)(jb / 4) * kc * 4;
int full = (jb + 4 <= nc);
int lim = nc - jb; if (lim > 4) lim = 4; if (lim < 0) lim = 0;
const long long *sq = P + (size_t)o->r[0] * ld + o->c[0] + jc + jb;
const long long *sq1 = (nt >= 2) ? P + (size_t)o->r[1] * ld + o->c[1] + jc + jb : 0;
if (full && nt <= 2) {
for (int k = 0; k < kc; k++) {
__m256i v = LDQ((const __m256i *)(sq + (size_t)(pc + k) * ld));
if (nt == 2) {
__m256i w = LDQ((const __m256i *)(sq1 + (size_t)(pc + k) * ld));
v = (o->s[1] > 0) ? _mm256_add_epi64(v, w) : _mm256_sub_epi64(v, w);
}
_mm256_store_si256((__m256i *)(q + (size_t)k * 4), _mm256_shuffle_epi32(v, 0xB1));
}
} else if (full) {
for (int k = 0; k < kc; k++) {
__m256i v = _mm256_setzero_si256();
for (int tt = 0; tt < nt; tt++) {
__m256i w = LDQ((const __m256i *)(P + (size_t)(o->r[tt] + pc + k) * ld + o->c[tt] + jc + jb));
v = (o->s[tt] < 0) ? _mm256_sub_epi64(v, w) : _mm256_add_epi64(v, w);
}
_mm256_store_si256((__m256i *)(q + (size_t)k * 4), _mm256_shuffle_epi32(v, 0xB1));
}
} else {
for (int k = 0; k < KC; k++) {
long long t[4] = {0, 0, 0, 0};
if (k < kc) {
int ncol = full ? 4 : lim;
for (int c = 0; c < ncol; c++) {
long long v = 0;
for (int tt = 0; tt < nt; tt++)
v += o->s[tt] < 0 ? -P[(size_t)(o->r[tt] + pc + k) * ld + o->c[tt] + jc + jb + c]
:  P[(size_t)(o->r[tt] + pc + k) * ld + o->c[tt] + jc + jb + c];
t[c] = v;
}
}
__m256i v = LDQ((const __m256i *)t);
_mm256_store_si256((__m256i *)(q + (size_t)k * 4), _mm256_shuffle_epi32(v, 0xB1));
}
}
}
}


template<int Sign>
static __attribute__((always_inline)) inline void packA_fixed64(const long long*s0,const long long*s1,int ld,int mc){
if constexpr(Sign){if((((uintptr_t)s1)&31)==0 && (ld&3)==0){
long long*d=(Apanel + 8);  
int rp=0;
for(;rp+1<mc;rp+=2){
#pragma GCC unroll 4
for(int k=0;k<64;k+=4){
__m256i v=LDQ((const __m256i*)(s0+k));
__m256i u=LDQ((const __m256i*)(s0+ld+k));
if constexpr(Sign) { __m256i w=_mm256_load_si256((const __m256i*)(s1+k));__m256i x=_mm256_load_si256((const __m256i*)(s1+ld+k));v=Sign>0?_mm256_add_epi64(v,w):_mm256_sub_epi64(v,w);u=Sign>0?_mm256_add_epi64(u,x):_mm256_sub_epi64(u,x); }
STQ((__m256i*)(d+k),v);
STQ((__m256i*)(d+KCP+k),u);
}
s0+=(size_t)2*ld;if constexpr(Sign)s1+=(size_t)2*ld;d+=2*KCP;
}
if(rp<mc){
#pragma GCC unroll 4
for(int k=0;k<64;k+=4){
__m256i v=LDQ((const __m256i*)(s0+k));
if constexpr(Sign) { __m256i w=_mm256_load_si256((const __m256i*)(s1+k));v=Sign>0?_mm256_add_epi64(v,w):_mm256_sub_epi64(v,w); }
STQ((__m256i*)(d+k),v);
}
s0+=ld;if constexpr(Sign)s1+=ld;d+=KCP;
}
return;
}}
long long*d=(Apanel + 8);  
for(int r=0;r<mc;r++){
#pragma GCC unroll 4
for(int k=0;k<64;k+=4){
__m256i v=LDQ((const __m256i*)(s0+k));
if constexpr(Sign) { __m256i w=LDQ((const __m256i*)(s1+k));v=Sign>0?_mm256_add_epi64(v,w):_mm256_sub_epi64(v,w); }
STQ((__m256i*)(d+k),v);
}
s0+=ld;if constexpr(Sign)s1+=ld;d+=KCP;
}
}
static void packA(const Opd*o,int ic,int mc,int pc,int kc){
if(kc==64 && pc==0 && o->nt<=2){
const long long*s0=o->p+(size_t)(o->r[0]+ic)*o->ld+o->c[0];
if(o->nt==1)packA_fixed64<0>(s0,nullptr,o->ld,mc);
else {const long long*s1=o->p+(size_t)(o->r[1]+ic)*o->ld+o->c[1];
if(o->s[1]>0)packA_fixed64<1>(s0,s1,o->ld,mc);else packA_fixed64<-1>(s0,s1,o->ld,mc);}
return;
}
packA_general(o,ic,mc,pc,kc);
}

template<int Sign>
static __attribute__((noinline)) void packB_fixed64(const long long*s0,const long long*s1,int ld){
if constexpr(Sign){if((((uintptr_t)s1)&31)==0 && (ld&3)==0){
for(int jb=0;jb<64;jb+=16){
long long*q0=Bpanel+(size_t)jb*64,*q1=q0+256,*q2=q1+256,*q3=q2+256;
const long long*r0=s0+jb,*r1=s1;
if constexpr(Sign)r1+=jb;
#pragma GCC unroll 1
for(int k=0;k<64;k+=2){
__m256i t0,t1,t2,t3,t4,t5,t6,t7;
{
__m256i v0=LDQ((const __m256i*)r0),v1=LDQ((const __m256i*)(r0+4)),v2=LDQ((const __m256i*)(r0+8)),v3=LDQ((const __m256i*)(r0+12));
if constexpr(Sign){
__m256i w0=_mm256_load_si256((const __m256i*)r1),w1=_mm256_load_si256((const __m256i*)(r1+4)),w2=_mm256_load_si256((const __m256i*)(r1+8)),w3=_mm256_load_si256((const __m256i*)(r1+12));
if constexpr(Sign>0){v0=_mm256_add_epi64(v0,w0);v1=_mm256_add_epi64(v1,w1);v2=_mm256_add_epi64(v2,w2);v3=_mm256_add_epi64(v3,w3);}
else {v0=_mm256_sub_epi64(v0,w0);v1=_mm256_sub_epi64(v1,w1);v2=_mm256_sub_epi64(v2,w2);v3=_mm256_sub_epi64(v3,w3);}
}
t0=_mm256_shuffle_epi32(v0,0xB1);t1=_mm256_shuffle_epi32(v1,0xB1);
t2=_mm256_shuffle_epi32(v2,0xB1);t3=_mm256_shuffle_epi32(v3,0xB1);
}
{
const long long*r2=r0+ld,*r3=r1; if constexpr(Sign) r3+=ld;
__m256i v0=LDQ((const __m256i*)r2),v1=LDQ((const __m256i*)(r2+4)),v2=LDQ((const __m256i*)(r2+8)),v3=LDQ((const __m256i*)(r2+12));
if constexpr(Sign){
__m256i w0=_mm256_load_si256((const __m256i*)r3),w1=_mm256_load_si256((const __m256i*)(r3+4)),w2=_mm256_load_si256((const __m256i*)(r3+8)),w3=_mm256_load_si256((const __m256i*)(r3+12));
if constexpr(Sign>0){v0=_mm256_add_epi64(v0,w0);v1=_mm256_add_epi64(v1,w1);v2=_mm256_add_epi64(v2,w2);v3=_mm256_add_epi64(v3,w3);}
else {v0=_mm256_sub_epi64(v0,w0);v1=_mm256_sub_epi64(v1,w1);v2=_mm256_sub_epi64(v2,w2);v3=_mm256_sub_epi64(v3,w3);}
}
t4=_mm256_shuffle_epi32(v0,0xB1);t5=_mm256_shuffle_epi32(v1,0xB1);
t6=_mm256_shuffle_epi32(v2,0xB1);t7=_mm256_shuffle_epi32(v3,0xB1);
}
_mm256_store_si256((__m256i*)q0,t0);_mm256_store_si256((__m256i*)(q0+4),t4);
_mm256_store_si256((__m256i*)q1,t1);_mm256_store_si256((__m256i*)(q1+4),t5);
_mm256_store_si256((__m256i*)q2,t2);_mm256_store_si256((__m256i*)(q2+4),t6);
_mm256_store_si256((__m256i*)q3,t3);_mm256_store_si256((__m256i*)(q3+4),t7);
q0+=8;q1+=8;q2+=8;q3+=8;r0+=(size_t)2*ld;if constexpr(Sign)r1+=(size_t)2*ld;
}
}
return;
}}
for(int jb=0;jb<64;jb+=16){
long long*q0=Bpanel+(size_t)jb*64,*q1=q0+256,*q2=q1+256,*q3=q2+256;
const long long*r0=s0+jb,*r1=s1;
if constexpr(Sign)r1+=jb;
#pragma GCC unroll 1
for(int k=0;k<64;k+=2){
__m256i t0,t1,t2,t3,t4,t5,t6,t7;
{
__m256i v0=LDQ((const __m256i*)r0),v1=LDQ((const __m256i*)(r0+4)),v2=LDQ((const __m256i*)(r0+8)),v3=LDQ((const __m256i*)(r0+12));
if constexpr(Sign){
__m256i w0=LDQ((const __m256i*)r1),w1=LDQ((const __m256i*)(r1+4)),w2=LDQ((const __m256i*)(r1+8)),w3=LDQ((const __m256i*)(r1+12));
if constexpr(Sign>0){v0=_mm256_add_epi64(v0,w0);v1=_mm256_add_epi64(v1,w1);v2=_mm256_add_epi64(v2,w2);v3=_mm256_add_epi64(v3,w3);}
else {v0=_mm256_sub_epi64(v0,w0);v1=_mm256_sub_epi64(v1,w1);v2=_mm256_sub_epi64(v2,w2);v3=_mm256_sub_epi64(v3,w3);}
}
t0=_mm256_shuffle_epi32(v0,0xB1);t1=_mm256_shuffle_epi32(v1,0xB1);
t2=_mm256_shuffle_epi32(v2,0xB1);t3=_mm256_shuffle_epi32(v3,0xB1);
}
{
const long long*r2=r0+ld,*r3=r1; if constexpr(Sign) r3+=ld;
__m256i v0=LDQ((const __m256i*)r2),v1=LDQ((const __m256i*)(r2+4)),v2=LDQ((const __m256i*)(r2+8)),v3=LDQ((const __m256i*)(r2+12));
if constexpr(Sign){
__m256i w0=LDQ((const __m256i*)r3),w1=LDQ((const __m256i*)(r3+4)),w2=LDQ((const __m256i*)(r3+8)),w3=LDQ((const __m256i*)(r3+12));
if constexpr(Sign>0){v0=_mm256_add_epi64(v0,w0);v1=_mm256_add_epi64(v1,w1);v2=_mm256_add_epi64(v2,w2);v3=_mm256_add_epi64(v3,w3);}
else {v0=_mm256_sub_epi64(v0,w0);v1=_mm256_sub_epi64(v1,w1);v2=_mm256_sub_epi64(v2,w2);v3=_mm256_sub_epi64(v3,w3);}
}
t4=_mm256_shuffle_epi32(v0,0xB1);t5=_mm256_shuffle_epi32(v1,0xB1);
t6=_mm256_shuffle_epi32(v2,0xB1);t7=_mm256_shuffle_epi32(v3,0xB1);
}
_mm256_store_si256((__m256i*)q0,t0);_mm256_store_si256((__m256i*)(q0+4),t4);
_mm256_store_si256((__m256i*)q1,t1);_mm256_store_si256((__m256i*)(q1+4),t5);
_mm256_store_si256((__m256i*)q2,t2);_mm256_store_si256((__m256i*)(q2+4),t6);
_mm256_store_si256((__m256i*)q3,t3);_mm256_store_si256((__m256i*)(q3+4),t7);
q0+=8;q1+=8;q2+=8;q3+=8;r0+=(size_t)2*ld;if constexpr(Sign)r1+=(size_t)2*ld;
}
}
}
static void packB(const Opd*o,int jc,int nc,int pc,int kc){
if(kc==64 && nc==64 && pc==0 && o->nt<=2){
const long long*s0=o->p+(size_t)o->r[0]*o->ld+o->c[0]+jc;
if(o->nt==1)packB_fixed64<0>(s0,nullptr,o->ld);
else {const long long*s1=o->p+(size_t)o->r[1]*o->ld+o->c[1]+jc;
if(o->s[1]>0)packB_fixed64<1>(s0,s1,o->ld);else packB_fixed64<-1>(s0,s1,o->ld);}
return;
}
packB_general(o,jc,nc,pc,kc);
}
static inline int effop(int base, int term) {    
if (base == 0) return term == 1 ? 0 : 2;
if (base == 1) return term == 2 ? 2 : 1;
return term == 2 ? 1 : 2;
}


static __attribute__((always_inline)) inline void leaf(int n, const Opd *Ao, const Opd *Bo,
long long *C1, int ldc1, int op1, long long *C2, int ldc2, int op2) {
int nb4 = n - (n & 3);
for (int jc = 0; jc < nb4; jc += NC) {
int nc = (nb4 - jc < NC) ? (nb4 - jc) : NC;
for (int pc = 0; pc < n; pc += KC) {
int kc = (n - pc < KC) ? (n - pc) : KC;
packB(Bo, jc, nc, pc, kc);
int e1 = (pc == 0) ? op1 : (op1 == 2 ? 2 : 1);
int e2 = (pc == 0) ? op2 : (op2 == 2 ? 2 : 1);
for (int ic = 0; ic < n; ic += MC) {
int mc = (n - ic < MC) ? (n - ic) : MC;
packA(Ao, ic, mc, pc, kc);
for (int ir = 0; ir < mc; ir += MR) {
int rows = (mc - ir < MR) ? (mc - ir) : MR;
const long long *ap = (Apanel + 8) + (size_t)ir * KCP * 1;  
for (int jg = 0; jg < nc; jg += 4) {
const long long *bp = Bpanel + (size_t)(jg / 4) * kc * 4;
mikro(kc / UU, ap, bp, C1 + (size_t)(ic + ir) * ldc1 + jc + jg, ldc1, e1,
C2 ? C2 + (size_t)(ic + ir) * ldc2 + jc + jg : 0, ldc2, e2, rows);
}
}
}
}
}
for (int j = nb4; j < n; j++)
for (int i = 0; i < n; i++) {
unsigned long long acc = 0;
for (int k = 0; k < n; k++) {
long long av = 0, bv = 0;
for (int t = 0; t < Ao->nt; t++)
av += Ao->s[t] < 0 ? -Ao->p[(size_t)(Ao->r[t] + i) * Ao->ld + Ao->c[t] + k]
:  Ao->p[(size_t)(Ao->r[t] + i) * Ao->ld + Ao->c[t] + k];
for (int t = 0; t < Bo->nt; t++)
bv += Bo->s[t] < 0 ? -Bo->p[(size_t)(Bo->r[t] + k) * Bo->ld + Bo->c[t] + j]
:  Bo->p[(size_t)(Bo->r[t] + k) * Bo->ld + Bo->c[t] + j];
acc += (unsigned long long)av * (unsigned long long)bv;
}
long long *cp = C1 + (size_t)i * ldc1 + j;
if (op1 == 0) *cp = (long long)acc;
else if (op1 == 1) *cp += (long long)acc;
else *cp -= (long long)acc;
if (C2) {
long long *cq = C2 + (size_t)i * ldc2 + j;
if (op2 == 0) *cq = (long long)acc;
else if (op2 == 1) *cq += (long long)acc;
else *cq -= (long long)acc;
}
}
}

template<int ASign,int BSign>
static __attribute__((noinline,noclone)) void leaf64_direct_sources(
const long long*a0,const long long*a1,int lda,
const long long*b0,const long long*b1,int ldb,long long*c,int ldc){
packB_fixed64<BSign>(b0,b1,ldb);
if constexpr(ASign==0){
if(lda*2==KCP){
packA_fixed64<0>(a0+(size_t)60*lda,a0+(size_t)60*lda,lda,4);
const long long *tail_a=Apanel+8;
long long *tail_c=c+(size_t)60*ldc;
for(int j=0;j<64;j+=4)
mikro_i(64,tail_a,Bpanel+(size_t)j*64,tail_c+j,ldc,0,nullptr,0,0,4);
for(int parity=0;parity<2;parity++){
for(int ic=0;ic<30;ic+=6){
const long long *native_a=a0+(size_t)(2*ic+parity)*lda;
long long *native_c=c+(size_t)(2*ic+parity)*ldc;
for(int j=0;j<64;j+=4)
mikro_i(64,native_a,Bpanel+(size_t)j*64,native_c+j,ldc*2,0,nullptr,0,0,6);
}
}
return;
}
}


{
const int id = 6;
const int icend = id > 0 ? 60 : -6;
if (true) {
const long long*ap=(Apanel+8);
if constexpr(ASign==0){
if(lda==KCP) ap=a0+(size_t)60*lda;
else packA_fixed64<ASign>(a0+(size_t)60*lda,a1+(size_t)60*lda,lda,4);
}else packA_fixed64<ASign>(a0+(size_t)60*lda,a1+(size_t)60*lda,lda,4);
for(int j=0;j<64;j+=4) mikro_i(64,ap,Bpanel+(size_t)j*64,c+(size_t)60*ldc+j,ldc,0,nullptr,0,0,4);
}
for(int ic = 54; ic >= 0; ic -= 6){
const long long*ap=(Apanel+8);
if constexpr(ASign==0){
if(lda==KCP) ap=a0+(size_t)ic*lda;
else packA_fixed64<ASign>(a0+(size_t)ic*lda,a1+(size_t)ic*lda,lda,6);
}else packA_fixed64<ASign>(a0+(size_t)ic*lda,a1+(size_t)ic*lda,lda,6);
for(int j=0;j<(64+0);j+=4) mikro_i(64,ap,Bpanel+(size_t)j*64,c+(size_t)ic*ldc+j,ldc,0,nullptr,0,0,6);
}
if (false) {
const long long*ap=(Apanel+8);
if constexpr(ASign==0){
if(lda==KCP) ap=a0+(size_t)60*lda;
else packA_fixed64<ASign>(a0+(size_t)60*lda,a1+(size_t)60*lda,lda,4);
}else packA_fixed64<ASign>(a0+(size_t)60*lda,a1+(size_t)60*lda,lda,4);
for(int j=0;j<64;j+=4) mikro_i(64,ap,Bpanel+(size_t)j*64,c+(size_t)60*ldc+j,ldc,0,nullptr,0,0,4);
}
}
}


static long long g_scratch[6u * 1024u * 1024u] __attribute__((aligned(2097152)));


static void cmb(long long *dst, int ldd, const long long *T, int ldt, int h, int sign, int op) {
__m256i sgn = _mm256_set1_epi64x(sign < 0 ? -1 : 0);
for (int i = 0; i < h; i++) {
const long long *t = T + (size_t)i * ldt;
long long *c = dst + (size_t)i * ldd;
int j = 0;
if (op == 0) {
for (; j + 4 <= h; j += 4) {
__m256i v = LDQ((const __m256i *)(t + j));
if (sign < 0) v = _mm256_sub_epi64(_mm256_setzero_si256(), v);
STQ((__m256i *)(c + j), v);
}
for (; j < h; j++) c[j] = sign < 0 ? -t[j] : t[j];
} else {
for (; j + 4 <= h; j += 4) {
__m256i v = LDQ((const __m256i *)(t + j));
__m256i w = LDQ((const __m256i *)(c + j));
if ((op == 1) != (sign < 0)) STQ((__m256i *)(c + j), _mm256_add_epi64(w, v));
else                         STQ((__m256i *)(c + j), _mm256_sub_epi64(w, v));
}
for (; j < h; j++) { if ((op == 1) != (sign < 0)) c[j] += t[j]; else c[j] -= t[j]; }
}
}
}


static long long material_A[1024u * 1024u] __attribute__((aligned(2097152)));
static long long material_B[1024u * 1024u] __attribute__((aligned(2097152)));

static long long material_C[512u * 512u] __attribute__((aligned(2097152)));
static long long material_D[512u * 512u] __attribute__((aligned(2097152)));
static void materializeN(const Opd *o, long long *dst, const int n) {
for (int i = 0; i < n; i++) {
long long *out = dst + (size_t)i * n;
int j = 0;
for (; j + 4 <= n; j += 4) {
__m256i value = _mm256_setzero_si256();
for (int t = 0; t < o->nt; t++) {
const long long *src = o->p + (size_t)(o->r[t] + i) * o->ld + o->c[t] + j;
__m256i part = LDQ((const __m256i *)src);
value = o->s[t] < 0 ? _mm256_sub_epi64(value, part) : _mm256_add_epi64(value, part);
}
STQ((__m256i *)(out + j), value);
}
for (; j < n; j++) {
unsigned long long value = 0;
for (int t = 0; t < o->nt; t++) {
unsigned long long part = (unsigned long long)o->p[(size_t)(o->r[t] + i) * o->ld + o->c[t] + j];
value = o->s[t] < 0 ? value - part : value + part;
}
out[j] = (long long)value;
}
}
}


static void mmxR(int n, const Opd *Ao, const Opd *Bo, long long *d, int ld, int op,
long long *T) {
if (n == 1024 && (Ao->nt > 1 || Bo->nt > 1)) {
Opd am, bm; const Opd *a = Ao, *b = Bo;
if (Ao->nt > 1) { materializeN(Ao, material_A, 1024); am = o1(material_A, n); a = &am; }
if (Bo->nt > 1) { materializeN(Bo, material_B, 1024); bm = o1(material_B, n); b = &bm; }
mmxR(n, a, b, d, ld, op, T);
return;
}
if (n <= CUTL || (n & 1) || Ao->nt > 2 || Bo->nt > 2) {
leaf(n, Ao, Bo, d, ld, op, 0, 0, 0); return; }

if (n == 512 && (Ao->nt > 1 || Bo->nt > 1)) {
Opd am, bm; const Opd *a = Ao, *b = Bo;
if (Ao->nt > 1) { materializeN(Ao, material_C, 512); am = o1(material_C, 512); a = &am; }
if (Bo->nt > 1) { materializeN(Bo, material_D, 512); bm = o1(material_D, 512); b = &bm; }
mmxR(n, a, b, d, ld, op, T);
return;
}
const int h = n >> 1;
Opd A11 = oq(Ao, 0, 0, h), A12 = oq(Ao, 0, 1, h), A21 = oq(Ao, 1, 0, h), A22 = oq(Ao, 1, 1, h);
Opd B11 = oq(Bo, 0, 0, h), B12 = oq(Bo, 0, 1, h), B21 = oq(Bo, 1, 0, h), B22 = oq(Bo, 1, 1, h);
long long *Q[4];
Q[0] = d; Q[1] = d + h; Q[2] = d + (size_t)h * ld; Q[3] = Q[2] + h;
long long *T2 = T + (size_t)h * h;
int wr[4] = {0, 0, 0, 0};
#define MK(qi, si, qj, sj, Ma, Mb) do { \
int oa = wr[qi] ? effop(1, (si)) : effop(op, (si)); \
int ob = wr[qj] ? effop(1, (sj)) : effop(op, (sj)); \
wr[qi] = 1; wr[qj] = 1; \
if (oa == 0) { \
mmxR(h, &(Ma), &(Mb), Q[qi], ld, 0, T); \
cmb(Q[qj], ld, Q[qi], ld, h, (sj), ob); \
} else { \
mmxR(h, &(Ma), &(Mb), T, h, 0, T2); \
cmb(Q[qi], ld, T, h, h, (si), oa); \
cmb(Q[qj], ld, T, h, h, (sj), ob); \
} \
} while (0) \

#define MK1(qi, si, Ma, Mb) do { \
int oa = wr[qi] ? effop(1, (si)) : effop(op, (si)); \
wr[qi] = 1; \
mmxR(h, &(Ma), &(Mb), Q[qi], ld, oa, T); \
} while (0)
{  
Opd Ma = oadd(&A11, &A22, 1), Mb = oadd(&B11, &B22, 1);
MK(0, 1, 3, 1, Ma, Mb);
}
{  
Opd Ma = oadd(&A21, &A22, 1), Mb = B11;
MK(2, 1, 3, 2, Ma, Mb);
}
{  
Opd Ma = A11, Mb = oadd(&B12, &B22, -1);
MK(1, 1, 3, 1, Ma, Mb);
}
{  
Opd Ma = A22, Mb = oadd(&B21, &B11, -1);
MK(0, 1, 2, 1, Ma, Mb);
}
{  
Opd Ma = oadd(&A11, &A12, 1), Mb = B22;
MK(0, 2, 1, 1, Ma, Mb);
}
{  
Opd Ma = oadd(&A21, &A11, -1), Mb = oadd(&B11, &B12, 1);
MK1(3, 1, Ma, Mb);
}
{  
Opd Ma = oadd(&A12, &A22, -1), Mb = oadd(&B21, &B22, 1);
MK1(0, 1, Ma, Mb);
}
#undef MK
#undef MK1
}


static inline void wg_store_nt(long long *p, __m256i v){ __asm__ volatile("vmovntdq %1,%0" : "=m"(*(__m256i*)p) : "x"(v)); }
static inline __m256i wg_load(const long long *p) { return LDQ((const __m256i *)p); }
static inline void wg_store(long long *p, __m256i v) { STQ((__m256i *)p, v); }

static long long wg_buf[5 * (size_t)(2048 * (2048 + 8)) + 4 * 512] __attribute__((aligned(2097152)));

static void wg_add(int h, long long *dst, const long long *a, int lda,
const long long *b, int ldb, int sg) {
if (h >= 512) {
for (int i = 0; i < h; i++) {
long long *d = dst + (size_t)i*h;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4) {
__m256i vx=wg_load(x+j), vy=wg_load(y+j);
wg_store_nt(d+j, sg > 0 ? _mm256_add_epi64(vx,vy) : _mm256_sub_epi64(vx,vy));
}
}
_mm_sfence();
return;
}
if((((uintptr_t)b)&31)==0 && (ldb&3)==0){
for (int i = 0; i < h; i++) {
long long *d = dst + (size_t)i*h;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
int j = 0;
for (; j + 8 <= h; j += 8) {
__m256i x0=wg_load(x+j), x1=wg_load(x+j+4), y0=_mm256_load_si256((const __m256i*)(y+j)), y1=_mm256_load_si256((const __m256i*)(y+j+4));
wg_store(d+j, sg > 0 ? _mm256_add_epi64(x0,y0) : _mm256_sub_epi64(x0,y0));
wg_store(d+j+4, sg > 0 ? _mm256_add_epi64(x1,y1) : _mm256_sub_epi64(x1,y1));
}
for (; j < h; j += 4) {
__m256i vx=wg_load(x+j), vy=_mm256_load_si256((const __m256i*)(y+j));
wg_store(d+j, sg > 0 ? _mm256_add_epi64(vx,vy) : _mm256_sub_epi64(vx,vy));
}
}
return;
}

for (int i = 0; i < h; i++) {
long long *d = dst + (size_t)i*h;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4) {
__m256i vx=wg_load(x+j), vy=wg_load(y+j);
wg_store(d+j, sg > 0 ? _mm256_add_epi64(vx,vy) : _mm256_sub_epi64(vx,vy));
}
}
}

static void wg_schain3(int h, long long *d1, long long *d2, long long *d3,
const long long *a11, int ld11, const long long *a21, int ld21,
const long long *a22, int ld22) {
if (h >= 512) {
for (int i = 0; i < h; i++) {
long long *p1 = d1 + (size_t)i*h, *p2 = d2 + (size_t)i*h, *p3 = d3 + (size_t)i*h;
const long long *x11 = a11 + (size_t)i*ld11, *x21 = a21 + (size_t)i*ld21, *x22 = a22 + (size_t)i*ld22;
for (int j = 0; j < h; j += 8) {
__m256i a0 = wg_load(x11+j), a1 = wg_load(x11+j+4);
__m256i b0 = wg_load(x21+j), b1 = wg_load(x21+j+4);
__m256i c0 = wg_load(x22+j), c1 = wg_load(x22+j+4);
__m256i s10 = _mm256_add_epi64(b0, c0), s11 = _mm256_add_epi64(b1, c1);
wg_store_nt(p1+j, s10); wg_store_nt(p1+j+4, s11);
wg_store_nt(p2+j, _mm256_sub_epi64(s10, a0)); wg_store_nt(p2+j+4, _mm256_sub_epi64(s11, a1));
wg_store_nt(p3+j, _mm256_sub_epi64(a0, b0)); wg_store_nt(p3+j+4, _mm256_sub_epi64(a1, b1));
}
}
_mm_sfence();
return;
}
if((((uintptr_t)a22)&31)==0 && (ld22&3)==0){
for (int i = 0; i < h; i++) {
long long *p1 = d1 + (size_t)i*h, *p2 = d2 + (size_t)i*h, *p3 = d3 + (size_t)i*h;
const long long *x11 = a11 + (size_t)i*ld11, *x21 = a21 + (size_t)i*ld21, *x22 = a22 + (size_t)i*ld22;
for (int j = 0; j < h; j += 4) {
__m256i v11 = wg_load(x11+j), v21 = wg_load(x21+j), v22 = _mm256_load_si256((const __m256i*)(x22+j));
__m256i s1 = _mm256_add_epi64(v21, v22);
wg_store(p1+j, s1);
wg_store(p2+j, _mm256_sub_epi64(s1, v11));
wg_store(p3+j, _mm256_sub_epi64(v11, v21));
}
}
return;
}

for (int i = 0; i < h; i++) {
long long *p1 = d1 + (size_t)i*h, *p2 = d2 + (size_t)i*h, *p3 = d3 + (size_t)i*h;
const long long *x11 = a11 + (size_t)i*ld11, *x21 = a21 + (size_t)i*ld21, *x22 = a22 + (size_t)i*ld22;
for (int j = 0; j < h; j += 4) {
__m256i v11 = wg_load(x11+j), v21 = wg_load(x21+j), v22 = wg_load(x22+j);
__m256i s1 = _mm256_add_epi64(v21, v22);
wg_store(p1+j, s1);
wg_store(p2+j, _mm256_sub_epi64(s1, v11));
wg_store(p3+j, _mm256_sub_epi64(v11, v21));
}
}
}

static void wg_schain4(int h,long long*d1,long long*d2,long long*d3,
long long*d4,int ld4,const long long*A,int lda){
const long long*A11=A,*A12=A+h,*A21=A+(size_t)h*lda,*A22=A21+h;
for(int t=0;t<h;t++){ int i=(t<(h>>1))?((h>>1)-1-t):(h-1-t+(h>>1));
 const long long*x11=A11+(size_t)i*lda,*x12=A12+(size_t)i*lda;
 const long long*x21=A21+(size_t)i*lda,*x22=A22+(size_t)i*lda;
 long long*p1=d1+(size_t)i*h,*p2=d2+(size_t)i*h,*p3=d3+(size_t)i*h,*p4=d4+(size_t)i*ld4;
 for(int j=0;j<h;j+=8){
  __m256i a0=wg_load(x11+j),a1=wg_load(x11+j+4);
  __m256i b0=wg_load(x12+j),b1=wg_load(x12+j+4);
  __m256i c0=wg_load(x21+j),c1=wg_load(x21+j+4);
  __m256i e0=wg_load(x22+j),e1=wg_load(x22+j+4);
  __m256i s10=_mm256_add_epi64(c0,e0),s11=_mm256_add_epi64(c1,e1);
  __m256i s20=_mm256_sub_epi64(s10,a0),s21=_mm256_sub_epi64(s11,a1);
  wg_store_nt(p1+j,s10);wg_store_nt(p1+j+4,s11);
  wg_store_nt(p2+j,s20);wg_store_nt(p2+j+4,s21);
  wg_store_nt(p3+j,_mm256_sub_epi64(a0,c0));wg_store_nt(p3+j+4,_mm256_sub_epi64(a1,c1));
  wg_store_nt(p4+j,_mm256_sub_epi64(b0,s20));wg_store_nt(p4+j+4,_mm256_sub_epi64(b1,s21));
 }
}
_mm_sfence();
}

static void wg_sub2(int h, long long *d, const long long *a, int lda, const long long *b, int ldb) {
if (h >= 512) {
for (int i = 0; i < h; i++) {
long long *dd = d + (size_t)i*h;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4)
wg_store_nt(dd+j, _mm256_sub_epi64(wg_load(x+j), wg_load(y+j)));
}
_mm_sfence();
return;
}
if((((uintptr_t)b)&31)==0 && (ldb&3)==0){
for (int i = 0; i < h; i++) {
long long *dd = d + (size_t)i*h;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4)
wg_store(dd+j, _mm256_sub_epi64(wg_load(x+j), _mm256_load_si256((const __m256i*)(y+j))));
}
return;
}

for (int i = 0; i < h; i++) {
long long *dd = d + (size_t)i*h;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4)
wg_store(dd+j, _mm256_sub_epi64(wg_load(x+j), wg_load(y+j)));
}
}
static void wg_add_ld(int h, long long *dst, int ldd, const long long *a, int lda,
const long long *b, int ldb, int sg) {
if (h >= 512) {
for (int i = 0; i < h; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4) {
__m256i vx=wg_load(x+j), vy=wg_load(y+j);
wg_store_nt(d+j, sg > 0 ? _mm256_add_epi64(vx,vy) : _mm256_sub_epi64(vx,vy));
}
}
_mm_sfence();
return;
}
for (int i = 0; i < h; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4) {
__m256i vx=wg_load(x+j), vy=wg_load(y+j);
wg_store(d+j, sg > 0 ? _mm256_add_epi64(vx,vy) : _mm256_sub_epi64(vx,vy));
}
}
}
static void wg_sub2_ld(int h, long long *dst, int ldd, const long long *a, int lda,
const long long *b, int ldb) {
if (h >= 512) {
for (int i = 0; i < h; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4)
wg_store_nt(d+j, _mm256_sub_epi64(wg_load(x+j), wg_load(y+j)));
}
_mm_sfence();
return;
}
for (int i = 0; i < h; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4)
wg_store(d+j, _mm256_sub_epi64(wg_load(x+j), wg_load(y+j)));
}
}
template<bool Reverse>
static void wg_mutate(int h, long long *dst, const long long *b, int ldb) {
if(((((uintptr_t)b)|((uintptr_t)dst))&31)==0 && ((ldb|h)&3)==0){
for (int i = h - 1; i >= 0; i--) {
long long *d = dst + (size_t)i*h; const long long *y=b+(size_t)i*ldb;
for (int j=0; j<h; j+=4) {
if constexpr(Reverse){
__m256i vy=wg_load(y+j),vd=_mm256_load_si256((const __m256i*)(d+j));
wg_store(d+j,_mm256_sub_epi64(vy,vd));
}else{
__m256i vd=wg_load(d+j),vy=_mm256_load_si256((const __m256i*)(y+j));
wg_store(d+j,_mm256_sub_epi64(vd,vy));
}
}
}
return;
}

for (int i = 0; i < h; i++) {
long long *d = dst + (size_t)i*h; const long long *y=b+(size_t)i*ldb;
for (int j=0; j<h; j+=4) {
__m256i vd=wg_load(d+j),vy=wg_load(y+j);
wg_store(d+j, Reverse ? _mm256_sub_epi64(vy,vd) : _mm256_sub_epi64(vd,vy));
}
}
}
static void wg_combine(int h, long long *C, int ldc, const long long *M1,
const long long *M2, const long long *M3, const long long *M4,
const long long *M5, const long long *M6, const long long *M7) {
for (int i=0; i<h; i++) {
const long long *a=M1+(size_t)i*ldc,*b=M2+(size_t)i*ldc,*c=M3+(size_t)i*ldc;
const long long *d=M4+(size_t)i*ldc,*e=M5+(size_t)i*h,*f=M6+(size_t)i*h,*g=M7+(size_t)i*h;
long long *c11=C+(size_t)i*ldc,*c12=c11+h,*c21=c11+(size_t)h*ldc,*c22=c21+h;
for (int j=0; j<h; j+=4) {
__m256i p1=wg_load(a+j),p2=wg_load(b+j),p3=wg_load(c+j),p4=wg_load(d+j);
__m256i p5=wg_load(e+j),p6=wg_load(f+j),p7=wg_load(g+j);
__m256i u2=_mm256_add_epi64(p1,p6),u3=_mm256_add_epi64(u2,p7);
__m256i u4=_mm256_add_epi64(u2,p5);
wg_store(c11+j,_mm256_add_epi64(p1,p2));
wg_store(c12+j,_mm256_add_epi64(u4,p3));
wg_store(c21+j,_mm256_sub_epi64(u3,p4));
wg_store(c22+j,_mm256_add_epi64(u3,p5));
}
}
}

static void wg_combine2(int h, long long *C, int ldc, const long long *M1,
const long long *M2, const long long *M3, int ld3, const long long *M4,
const long long *M5, const long long *M6, const long long *M7) {
for (int i=0; i<h; i++) {
const long long *a=M1+(size_t)i*ldc,*b=M2+(size_t)i*ldc,*c=M3+(size_t)i*ld3;
const long long *d=M4+(size_t)i*ldc,*e=M5+(size_t)i*h,*f=M6+(size_t)i*h,*g=M7+(size_t)i*h;
long long *c11=C+(size_t)i*ldc,*c12=c11+h,*c21=c11+(size_t)h*ldc,*c22=c21+h;
for (int j=0; j<h; j+=4) {
__m256i p1=wg_load(a+j),p2=wg_load(b+j),p3=wg_load(c+j),p4=wg_load(d+j);
__m256i p5=wg_load(e+j),p6=wg_load(f+j),p7=wg_load(g+j);
__m256i u2=_mm256_add_epi64(p1,p6),u3=_mm256_add_epi64(u2,p7);
__m256i u4=_mm256_add_epi64(u2,p5);
wg_store(c11+j,_mm256_add_epi64(p1,p2));
wg_store(c12+j,_mm256_add_epi64(u4,p3));
wg_store(c21+j,_mm256_sub_epi64(u3,p4));
wg_store(c22+j,_mm256_add_epi64(u3,p5));
}
}
}

static long long wg_buf_mini[5 * 64 * 64 + 4 * 512] __attribute__((aligned(2097152)));
static void winograd_prod128(int n, const long long *A, int lda, const long long *B,
int ldb, long long *C, int ldc) {
const int h=n/2; const size_t sz=(size_t)h*h; const size_t sg=(size_t)h*(size_t)(h+8);  
long long *M1=C,*M2=C+h,*M3=C+(size_t)h*ldc,*M4=M3+h;
long long *M5=wg_buf_mini,*M6=M5+sg+520,*M7=M6+sg+520;
const long long *a11=A,*a12=A+h,*a21=A+(size_t)h*lda,*a22=a21+h;
const long long *b11=B,*b12=B+h,*b21=B+(size_t)h*ldb,*b22=b21+h;
leaf64_direct_sources<-1,1>(a21,a11,lda,b11,b12,ldb,M6,h);
leaf64_direct_sources<1,0>(a11,a12,lda,b22,b22,ldb,M5,h);
leaf64_direct_sources<-1,1>(a12,a22,lda,b21,b22,ldb,M7,h);
leaf64_direct_sources<0,-1>(a22,a22,lda,b21,b11,ldb,M4,ldc);
leaf64_direct_sources<1,0>(a21,a22,lda,b11,b11,ldb,M2,ldc);
leaf64_direct_sources<1,1>(a11,a22,lda,b11,b22,ldb,M1,ldc);
leaf64_direct_sources<0,-1>(a11,a11,lda,b12,b22,ldb,M3,ldc);
for (int i=0;i<h;i++) {
const long long *m1=M1+(size_t)i*ldc,*m2=M2+(size_t)i*ldc,*m3=M3+(size_t)i*ldc,*m4=M4+(size_t)i*ldc;
const long long *m5=M5+(size_t)i*h,*m6=M6+(size_t)i*h,*m7=M7+(size_t)i*h;
long long *c11=C+(size_t)i*ldc,*c12=c11+h,*c21=c11+(size_t)h*ldc,*c22=c21+h;
#pragma GCC unroll 2
for (int j=0;j<h;j+=4) {
__m256i p1=wg_load(m1+j),p2=wg_load(m2+j),p3=wg_load(m3+j),p4=wg_load(m4+j);
__m256i p5=wg_load(m5+j),p6=wg_load(m6+j),p7=wg_load(m7+j);
wg_store(c11+j,_mm256_add_epi64(_mm256_sub_epi64(_mm256_add_epi64(p1,p4),p5),p7));
wg_store(c12+j,_mm256_add_epi64(p3,p5));
wg_store(c21+j,_mm256_add_epi64(p2,p4));
wg_store(c22+j,_mm256_add_epi64(_mm256_add_epi64(_mm256_sub_epi64(p1,p2),p3),p6));
}
}
}



#define WG256_SZ (128*128)

static void winograd_prod256_inner(int n, const long long *A, int lda, const long long *B,
int ldb, long long *C, int ldc);
static long long l4q_apack[256 * 256] __attribute__((aligned(4096)));
static void winograd_prod256(int n, const long long *A, int lda, const long long *B,
int ldb, long long *C, int ldc) {
if (lda != 4096) {    
winograd_prod256_inner(n, A, lda, B, ldb, C, ldc);
return;
}
for (int i = 0; i < n; i++) {
const long long *src = A + (size_t)i * lda; long long *dst = l4q_apack + (size_t)i * n;
int j=0;
for (; j+4<=n; j+=4) wg_store(dst+j,wg_load(src+j));
for (;j<n;j++) dst[j]=src[j];
}
winograd_prod256_inner(n, l4q_apack, n, B, ldb, C, ldc);
}
static void winograd_prod256_inner(int n, const long long *A, int lda, const long long *B,
int ldb, long long *C, int ldc) {
const int h=n/2; const size_t sz=(size_t)h*h; const size_t sg=(size_t)h*(size_t)(h+8);  
long long *M1=C,*M2=C+h,*M3=C+(size_t)h*ldc,*M4=M3+h;
long long *M5=g_scratch,*M6=M5+sg+512,*M7=M6+sg+512,*P=M7+sg+512,*Q=P+sg+512;
const long long *A11=A,*A12=A+h,*A21=A+(size_t)h*lda,*A22=A21+h;
const long long *B11=B,*B12=B+h,*B21=B+(size_t)h*ldb,*B22=B21+h;
#define PROD4(X,Y,Z,LX,LY,LZ) do { Opd ao=o1((X),(LX)),bo=o1((Y),(LY)); \
winograd_prod128(h,(X),(LX),(Y),(LY),(Z),(LZ)); } while(0)
PROD4(A11,B11,M1,lda,ldb,ldc);
PROD4(A12,B21,M2,lda,ldb,ldc);
wg_add(h,P,A21,lda,A22,lda,+1);
wg_add(h,Q,B12,ldb,B11,ldb,-1);
PROD4(P,Q,M5,h,h,h);
wg_mutate<false>(h,P,A11,lda);
wg_mutate<true>(h,Q,B22,ldb);
PROD4(P,Q,M6,h,h,h);
wg_mutate<true>(h,P,A12,lda);
PROD4(P,B22,M3,h,ldb,ldc);
wg_mutate<false>(h,Q,B21,ldb);
PROD4(A22,Q,M4,lda,h,ldc);
wg_add(h,P,A11,lda,A21,lda,-1);
wg_add(h,Q,B22,ldb,B12,ldb,-1);
PROD4(P,Q,M7,h,h,h);
#undef PROD4
wg_combine(h,C,ldc,M1,M2,M3,M4,M5,M6,M7);
}

static long long wg_buf2[5 * (size_t)(1024 * (1024 + 8)) + 4 * 512] __attribute__((aligned(2097152)));
static long long wg_buf_s2[2 * 2048 * 2048 + 2 * 512] __attribute__((aligned(2097152)));
static long long wg_buf2_s2[2 * (size_t)(1024 * (1024 + 8)) + 1 * 512] __attribute__((aligned(2097152)));
static long long wg_buf1[5 * (size_t)(512 * (512 + 8)) + 4 * 256] __attribute__((aligned(2097152)));
static long long wg_buf0[5 * (size_t)(256 * (256 + 8)) + 4 * 512] __attribute__((aligned(2097152)));
static void winograd_leaf512(int n, const long long *A, int lda, const long long *B, int ldb,
long long *C, int ldc) {
const int h=n/2; const size_t sz=(size_t)h*h; const size_t sg=(size_t)h*(size_t)(h+8);  
long long *M1=C,*M2=C+h,*M3=C+(size_t)h*ldc,*M4=M3+h;
long long *M5=wg_buf0,*M6=M5+sg+512,*M7=M6+sg+512,*P=M7+sg+512,*Q=P+sg+512;
const long long *A11=A,*A12=A+h,*A21=A+(size_t)h*lda,*A22=A21+h;
const long long *B11=B,*B12=B+h,*B21=B+(size_t)h*ldb,*B22=B21+h;
#define PROD3(X,Y,Z,LX,LY,LZ) do { winograd_prod256(h,(X),(LX),(Y),(LY),(Z),(LZ)); } while(0)
PROD3(A11,B11,M1,lda,ldb,ldc);
PROD3(A12,B21,M2,lda,ldb,ldc);
wg_add(h,P,A21,lda,A22,lda,+1);
wg_add(h,Q,B12,ldb,B11,ldb,-1);
PROD3(P,Q,M5,h,h,h);
wg_mutate<false>(h,P,A11,lda);
wg_mutate<true>(h,Q,B22,ldb);
PROD3(P,Q,M6,h,h,h);
wg_mutate<true>(h,P,A12,lda);
PROD3(P,B22,M3,h,ldb,ldc);
wg_mutate<false>(h,Q,B21,ldb);
PROD3(A22,Q,M4,lda,h,ldc);
wg_add(h,P,A11,lda,A21,lda,-1);
wg_add(h,Q,B22,ldb,B12,ldb,-1);
PROD3(P,Q,M7,h,h,h);
#undef PROD3
wg_combine(h,C,ldc,M1,M2,M3,M4,M5,M6,M7);
}

static void winograd_grandchild(int n,const long long*A,int lda,const long long*B,int ldb,long long*C,int ldc);

/* ---- v7: N-convention helpers (top half of destination negated, zero extra uops) ---- */
static inline void wg_store_nt2(long long *p, __m256i v){ wg_store_nt(p,v); }
/* dst = a - b on bottom half; dst = b - a on top half (S-convention output) */
static void wg_sub2_ld_n(int h, long long *dst, int ldd, const long long *a, int lda,
const long long *b, int ldb) {
const int hm = h >> 1;
for (int i = hm; i < h; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4)
wg_store_nt(d+j, _mm256_sub_epi64(wg_load(x+j), wg_load(y+j)));
}
for (int i = 0; i < hm; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = a + (size_t)i*lda, *y = b + (size_t)i*ldb;
for (int j = 0; j < h; j += 4)
wg_store_nt(d+j, _mm256_sub_epi64(wg_load(y+j), wg_load(x+j)));
}
_mm_sfence();
}
/* Q2' = S*(b22 - q1'): bottom = b22 - q1 ; top = -(b22 + q1) */
static void wg_q2n(int h, long long *dst, int ldd, const long long *b22, int ld22,
const long long *q1, int ld1) {
const int hm = h >> 1; const __m256i zero = _mm256_setzero_si256();
for (int i = hm; i < h; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = b22 + (size_t)i*ld22, *y = q1 + (size_t)i*ld1;
for (int j = 0; j < h; j += 4)
wg_store_nt(d+j, _mm256_sub_epi64(wg_load(x+j), wg_load(y+j)));
}
for (int i = 0; i < hm; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = b22 + (size_t)i*ld22, *y = q1 + (size_t)i*ld1;
for (int j = 0; j < h; j += 4) {
__m256i v = _mm256_add_epi64(wg_load(x+j), wg_load(y+j));
wg_store_nt(d+j, _mm256_sub_epi64(zero, v));
}
}
_mm_sfence();
}
/* Q3' = S*(q2' - b21): bottom = q2 - b21 ; top = q2 + b21 */
static void wg_q3n(int h, long long *dst, int ldd, const long long *q2, int ld2,
const long long *b21, int ld21) {
const int hm = h >> 1;
for (int i = hm; i < h; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = q2 + (size_t)i*ld2, *y = b21 + (size_t)i*ld21;
for (int j = 0; j < h; j += 4)
wg_store_nt(d+j, _mm256_sub_epi64(wg_load(x+j), wg_load(y+j)));
}
for (int i = 0; i < hm; i++) {
long long *d = dst + (size_t)i*ldd;
const long long *x = q2 + (size_t)i*ld2, *y = b21 + (size_t)i*ld21;
for (int j = 0; j < h; j += 4)
wg_store_nt(d+j, _mm256_add_epi64(wg_load(x+j), wg_load(y+j)));
}
_mm_sfence();
}
/* combine with p1 negated (because the child's M1 uses the S-convention B11) */
static void wg_combine2n(int h, long long *C, int ldc, const long long *M1,
const long long *M2, const long long *M3, int ld3, const long long *M4,
const long long *M5, const long long *M6, const long long *M7) {
for (int i=0; i<h; i++) {
const long long *a=M1+(size_t)i*ldc,*b=M2+(size_t)i*ldc,*c=M3+(size_t)i*ld3;
const long long *d=M4+(size_t)i*ldc,*e=M5+(size_t)i*h,*f=M6+(size_t)i*h,*g=M7+(size_t)i*h;
long long *c11=C+(size_t)i*ldc,*c12=c11+h,*c21=c11+(size_t)h*ldc,*c22=c21+h;
for (int j=0; j<h; j+=4) {
__m256i p1=wg_load(a+j),p2=wg_load(b+j),p3=wg_load(c+j),p4=wg_load(d+j);
__m256i p5=wg_load(e+j),p6=wg_load(f+j),p7=wg_load(g+j);
__m256i u2=_mm256_sub_epi64(p6,p1),u3=_mm256_add_epi64(u2,p7);
__m256i u4=_mm256_add_epi64(u2,p5);
wg_store(c11+j,_mm256_sub_epi64(p2,p1));
wg_store(c12+j,_mm256_add_epi64(u4,p3));
wg_store_nt(c21+j,_mm256_sub_epi64(u3,p4));
wg_store(c22+j,_mm256_add_epi64(u3,p5));
}
}
_mm_sfence();
}

static void winograd_child(int n, const long long *A, int lda, const long long *B, int ldb,
long long *C, int ldc) {
const int h=n/2; const size_t sz=(size_t)h*h; const size_t sg=(size_t)h*(size_t)(h+8);  
long long *M1=C,*M2=C+h,*M3=C+(size_t)h*ldc,*M4=M3+h;
long long *M5=wg_buf2,*M6=M5+sg+512,*M7=M6+sg+512,*P=M7+sg+512,*Q=P+sg+512;
long long *P2=wg_buf2_s2,*P3=P2+sg+512;
const long long *A11=A,*A12=A+h,*A21=A+(size_t)h*lda,*A22=A21+h;
const long long *B11=B,*B12=B+h,*B21=B+(size_t)h*ldb,*B22=B21+h;
#define PROD2(X,Y,Z,LX,LY,LZ) do { winograd_grandchild(h,(X),(LX),(Y),(LY),(Z),(LZ)); } while(0)
PROD2(A11,B11,M1,lda,ldb,ldc);
PROD2(A12,B21,M2,lda,ldb,ldc);
wg_schain3(h,P,P2,P3,A11,lda,A21,lda,A22,lda);
wg_add(h,Q,B12,ldb,B11,ldb,-1);
PROD2(P,Q,M5,h,h,h);
wg_mutate<true>(h,Q,B22,ldb);
PROD2(P2,Q,M6,h,h,h);
wg_sub2(h,P,A12,lda,P2,h);    
PROD2(P,B22,M3,h,ldb,ldc);
wg_mutate<false>(h,Q,B21,ldb);
PROD2(A22,Q,M4,lda,h,ldc);
wg_add(h,Q,B22,ldb,B12,ldb,-1);
PROD2(P3,Q,M7,h,h,h);
#undef PROD2
wg_combine(h,C,ldc,M1,M2,M3,M4,M5,M6,M7);
}


/* v7 child: B operand stored in the N-convention (top half negated).  B-chain:
   Q4 = B12'+B22', Q2 = Q4-B11', Q1 = B11'-B12'  (plain schain3 on stored quadrants),
   Q3 = Q2-B21';  M1 = A11*B11' = -trueM1 -> combine2n. */

/* v8: fused top B chain in S-convention (top half negated) with schain3-style codegen.
   bottom rows: q4=b22-b12, q2=q4+b11, q1=b12-b11
   top rows   : q4=b12-b22, q2=q4-b11, q1=b11-b12  (= -true, i.e. S-convention) */
static void wg_bfuse_S(int h, long long *q1, int ld1, long long *q2, int ld2,
long long *q4, int ld4, const long long *b11, const long long *b12, const long long *b22, int ldb) {
const int hm = h >> 1;
for (int i = hm; i < h; i++) {
long long *o1 = q1 + (size_t)i*ld1, *o2 = q2 + (size_t)i*ld2, *o4 = q4 + (size_t)i*ld4;
const long long *x11 = b11 + (size_t)i*ldb, *x12 = b12 + (size_t)i*ldb, *x22 = b22 + (size_t)i*ldb;
for (int j = 0; j < h; j += 4) {
__m256i v11=wg_load(x11+j), v12=wg_load(x12+j), v22=wg_load(x22+j);
__m256i d4=_mm256_sub_epi64(v22,v12);
wg_store_nt(o4+j, d4);
wg_store_nt(o2+j, _mm256_add_epi64(d4,v11));
wg_store_nt(o1+j, _mm256_sub_epi64(v12,v11));
}
}
for (int i = 0; i < hm; i++) {
long long *o1 = q1 + (size_t)i*ld1, *o2 = q2 + (size_t)i*ld2, *o4 = q4 + (size_t)i*ld4;
const long long *x11 = b11 + (size_t)i*ldb, *x12 = b12 + (size_t)i*ldb, *x22 = b22 + (size_t)i*ldb;
for (int j = 0; j < h; j += 4) {
__m256i v11=wg_load(x11+j), v12=wg_load(x12+j), v22=wg_load(x22+j);
__m256i d4=_mm256_sub_epi64(v12,v22);
wg_store_nt(o4+j, d4);
wg_store_nt(o2+j, _mm256_sub_epi64(d4,v11));
wg_store_nt(o1+j, _mm256_sub_epi64(v11,v12));
}
}
_mm_sfence();
}
/* combine with explicit strides for all 7 products (p1 sign positive) */
static void wg_combine7(int h, long long *C, int ldc,
const long long *M1,int l1,const long long *M2,int l2,const long long *M3,int l3,
const long long *M4,int l4,const long long *M5,int l5,const long long *M6,int l6,
const long long *M7,int l7) {
__asm__ volatile(".space 48,0x90");

for (int i=0; i<h; i++) {
const long long *a=M1+(size_t)i*l1,*b=M2+(size_t)i*l2,*c=M3+(size_t)i*l3,*d=M4+(size_t)i*l4;
const long long *e=M5+(size_t)i*l5,*f=M6+(size_t)i*l6,*g=M7+(size_t)i*l7;
long long *c11=C+(size_t)i*ldc,*c12=c11+h,*c21=c11+(size_t)h*ldc,*c22=c21+h;
for (int j=0; j<h; j+=8) {
__m256i p1a=wg_load(a+j),p1b=wg_load(a+j+4);
__m256i p2a=wg_load(b+j),p2b=wg_load(b+j+4);
__m256i p5a=wg_load(e+j),p5b=wg_load(e+j+4);
__m256i p6a=wg_load(f+j),p6b=wg_load(f+j+4);
__m256i p7a=wg_load(g+j),p7b=wg_load(g+j+4);
__m256i u2a=_mm256_add_epi64(p1a,p6a), u2b=_mm256_add_epi64(p1b,p6b);
__m256i u3a=_mm256_add_epi64(u2a,p7a), u3b=_mm256_add_epi64(u2b,p7b);
__m256i u4a=_mm256_add_epi64(u2a,p5a), u4b=_mm256_add_epi64(u2b,p5b);
wg_store(c11+j,_mm256_add_epi64(p1a,p2a)); wg_store(c11+j+4,_mm256_add_epi64(p1b,p2b));
wg_store(c12+j,_mm256_add_epi64(u4a,wg_load(c+j))); wg_store(c12+j+4,_mm256_add_epi64(u4b,wg_load(c+j+4)));
wg_store_nt(c21+j,_mm256_sub_epi64(u3a,wg_load(d+j))); wg_store_nt(c21+j+4,_mm256_sub_epi64(u3b,wg_load(d+j+4)));
wg_store_nt(c22+j,_mm256_add_epi64(u3a,p5a)); wg_store_nt(c22+j+4,_mm256_add_epi64(u3b,p5b));
}
}
_mm_sfence();
}


/* v9: normal-convention fused B chain: q4=b22-b12, q2=q4+b11, q1=b12-b11 (true values) */
static void wg_bfuse_n(int h, long long *q1, long long *q2, long long *q4,
const long long *b11, const long long *b12, const long long *b22, int ldb) {
for (int i = 0; i < h; i++) {
long long *o1 = q1 + (size_t)i*h, *o2 = q2 + (size_t)i*h, *o4 = q4 + (size_t)i*h;
const long long *x11 = b11 + (size_t)i*ldb, *x12 = b12 + (size_t)i*ldb, *x22 = b22 + (size_t)i*ldb;
for (int j = 0; j < h; j += 4) {
__m256i v11=wg_load(x11+j), v12=wg_load(x12+j), v22=wg_load(x22+j);
__m256i d4=_mm256_sub_epi64(v22,v12);
wg_store_nt(o4+j, d4);
wg_store_nt(o2+j, _mm256_add_epi64(d4,v11));
wg_store_nt(o1+j, _mm256_sub_epi64(v12,v11));
}
}
_mm_sfence();
}

static void wg_bfuse_S4(int h, long long *q1, int ld1, long long *q2, int ld2,
long long *q4, int ld4, long long *q3,int ld3,const long long*b21, const long long *b11, const long long *b12, const long long *b22, int ldb) {
const int hm = h >> 1;
for (int i = hm; i < h; i++) {
long long *o1 = q1 + (size_t)i*ld1, *o2 = q2 + (size_t)i*ld2, *o4 = q4 + (size_t)i*ld4;
long long *o3=q3+(size_t)i*ld3; const long long *x21=b21+(size_t)i*ldb;
const long long *x11 = b11 + (size_t)i*ldb, *x12 = b12 + (size_t)i*ldb, *x22 = b22 + (size_t)i*ldb;
for (int j = 0; j < h; j += 8) {
__m256i c0=wg_load(x11+j), c1=wg_load(x11+j+4);
__m256i b0=wg_load(x12+j), b1=wg_load(x12+j+4);
__m256i e0=wg_load(x22+j), e1=wg_load(x22+j+4);
__m256i f0=wg_load(x21+j), f1=wg_load(x21+j+4);
__m256i d40=_mm256_sub_epi64(e0,b0), d41=_mm256_sub_epi64(e1,b1);
__m256i d20=_mm256_add_epi64(d40,c0), d21=_mm256_add_epi64(d41,c1);
wg_store_nt(o4+j, d40); wg_store_nt(o4+j+4, d41);
wg_store_nt(o2+j, d20); wg_store_nt(o2+j+4, d21);
wg_store_nt(o3+j, _mm256_sub_epi64(d20,f0)); wg_store_nt(o3+j+4, _mm256_sub_epi64(d21,f1));
wg_store_nt(o1+j, _mm256_sub_epi64(b0,c0)); wg_store_nt(o1+j+4, _mm256_sub_epi64(b1,c1));
}
}
for (int i = 0; i < hm; i++) {
long long *o1 = q1 + (size_t)i*ld1, *o2 = q2 + (size_t)i*ld2, *o4 = q4 + (size_t)i*ld4;
long long *o3=q3+(size_t)i*ld3; const long long *x21=b21+(size_t)i*ldb;
const long long *x11 = b11 + (size_t)i*ldb, *x12 = b12 + (size_t)i*ldb, *x22 = b22 + (size_t)i*ldb;
for (int j = 0; j < h; j += 8) {
__m256i c0=wg_load(x11+j), c1=wg_load(x11+j+4);
__m256i b0=wg_load(x12+j), b1=wg_load(x12+j+4);
__m256i e0=wg_load(x22+j), e1=wg_load(x22+j+4);
__m256i f0=wg_load(x21+j), f1=wg_load(x21+j+4);
__m256i d40=_mm256_sub_epi64(b0,e0), d41=_mm256_sub_epi64(b1,e1);
__m256i d20=_mm256_sub_epi64(d40,c0), d21=_mm256_sub_epi64(d41,c1);
wg_store_nt(o4+j, d40); wg_store_nt(o4+j+4, d41);
wg_store_nt(o2+j, d20); wg_store_nt(o2+j+4, d21);
wg_store_nt(o3+j, _mm256_add_epi64(d20,f0)); wg_store_nt(o3+j+4, _mm256_add_epi64(d21,f1));
wg_store_nt(o1+j, _mm256_sub_epi64(c0,b0)); wg_store_nt(o1+j+4, _mm256_sub_epi64(c1,b1));
}
}
_mm_sfence();
}

template<bool NegatedB>
static void wg_bfuse_child4(int h,long long*q1,long long*q2,long long*q4,
 long long*q3,int ld3,const long long*B,int ldb){
 const long long*b11=B,*b12=B+h,*b21=B+(size_t)h*ldb,*b22=b21+h;
 for(int i=0;i<h;i++){
  const long long*x11=b11+(size_t)i*ldb,*x12=b12+(size_t)i*ldb;
  const long long*x21=b21+(size_t)i*ldb,*x22=b22+(size_t)i*ldb;
  long long*o1=q1+(size_t)i*h,*o2=q2+(size_t)i*h,*o4=q4+(size_t)i*h,*o3=q3+(size_t)i*ld3;
  for(int j=0;j<h;j+=8){
   __m256i a0=wg_load(x11+j),a1=wg_load(x11+j+4);
   __m256i b0=wg_load(x12+j),b1=wg_load(x12+j+4);
   __m256i c0=wg_load(x21+j),c1=wg_load(x21+j+4);
   __m256i e0=wg_load(x22+j),e1=wg_load(x22+j+4);
   __m256i d40,d41,d20,d21,d10,d11;
   if constexpr(NegatedB){d40=_mm256_add_epi64(b0,e0);d41=_mm256_add_epi64(b1,e1);d20=_mm256_sub_epi64(d40,a0);d21=_mm256_sub_epi64(d41,a1);d10=_mm256_sub_epi64(a0,b0);d11=_mm256_sub_epi64(a1,b1);}
   else{d40=_mm256_sub_epi64(e0,b0);d41=_mm256_sub_epi64(e1,b1);d20=_mm256_add_epi64(d40,a0);d21=_mm256_add_epi64(d41,a1);d10=_mm256_sub_epi64(b0,a0);d11=_mm256_sub_epi64(b1,a1);}
   wg_store_nt(o1+j,d10);wg_store_nt(o1+j+4,d11);
   wg_store_nt(o2+j,d20);wg_store_nt(o2+j+4,d21);
   wg_store_nt(o4+j,d40);wg_store_nt(o4+j+4,d41);
   wg_store_nt(o3+j,_mm256_sub_epi64(d20,c0));wg_store_nt(o3+j+4,_mm256_sub_epi64(d21,c1));
  }
 }
 _mm_sfence();
}
template<bool NegatedB>
static void wg_combine2_stride4(int h, long long *C, int ldc, const long long *M1,
const long long *M2, const long long *M3, int ld3, const long long *M4, int ld4,
const long long *M5, const long long *M6, const long long *M7) {
__asm__ volatile(".space 32,0x90");
for (int t=0; t<h; t++) { int i = (t < (h>>1)) ? ((h>>1) - 1 - t) : (h - 1 - t + (h>>1));
const long long *a=M1+(size_t)i*ldc,*b=M2+(size_t)i*ldc,*c=M3+(size_t)i*ld3;
const long long *d=M4+(size_t)i*ld4,*e=M5+(size_t)i*h,*f=M6+(size_t)i*h,*g=M7+(size_t)i*h;
long long *c11=C+(size_t)i*ldc,*c12=c11+h,*c21=c11+(size_t)h*ldc,*c22=c21+h;
for (int j=0; j<h; j+=8) {
__m256i p1a=wg_load(a+j),p1b=wg_load(a+j+4);
__m256i p2a=wg_load(b+j),p2b=wg_load(b+j+4);
__m256i p3a=wg_load(c+j),p3b=wg_load(c+j+4);
__m256i p4a=wg_load(d+j),p4b=wg_load(d+j+4);
__m256i p5a=wg_load(e+j),p5b=wg_load(e+j+4);
__m256i p6a=wg_load(f+j),p6b=wg_load(f+j+4);
__m256i p7a=wg_load(g+j),p7b=wg_load(g+j+4);
__m256i u2a=NegatedB?_mm256_sub_epi64(p6a,p1a):_mm256_add_epi64(p6a,p1a);
__m256i u2b=NegatedB?_mm256_sub_epi64(p6b,p1b):_mm256_add_epi64(p6b,p1b);
__m256i u3a=_mm256_add_epi64(u2a,p7a), u3b=_mm256_add_epi64(u2b,p7b);
__m256i u4a=_mm256_add_epi64(u2a,p5a), u4b=_mm256_add_epi64(u2b,p5b);
wg_store(c11+j,NegatedB?_mm256_sub_epi64(p2a,p1a):_mm256_add_epi64(p2a,p1a));
wg_store(c11+j+4,NegatedB?_mm256_sub_epi64(p2b,p1b):_mm256_add_epi64(p2b,p1b));
wg_store(c12+j,_mm256_add_epi64(u4a,p3a)); wg_store(c12+j+4,_mm256_add_epi64(u4b,p3b));
wg_store_nt(c21+j,_mm256_sub_epi64(u3a,p4a)); wg_store_nt(c21+j+4,_mm256_sub_epi64(u3b,p4b));
wg_store_nt(c22+j,_mm256_add_epi64(u3a,p5a)); wg_store_nt(c22+j+4,_mm256_add_epi64(u3b,p5b));
}
}
_mm_sfence();
}


static long long wg_buf1_s2[2*(size_t)(512*(512+8))+256] __attribute__((aligned(2097152)));
static void winograd_grandchild(int n, const long long *A, int lda, const long long *B, int ldb,
long long *C, int ldc) {
const int h=n/2; const size_t sg=(size_t)h*(size_t)(h+8);
long long *M1=C,*M2=C+h,*M3=C+(size_t)h*ldc,*M4=M3+h;
long long *R1=wg_buf1,*R2=R1+sg+256,*R3=R2+sg+256,*R4=R3+sg+256,*R5=R4+sg+256;
long long *S2=wg_buf1_s2,*S3=S2+sg+256;
const long long *A11=A,*A12=A+h,*A21=A+(size_t)h*lda,*A22=A21+h;
const long long *B11=B,*B12=B+h,*B21=B+(size_t)h*ldb,*B22=B21+h;
#define PROD2(X,Y,Z,LX,LY,LZ) do { winograd_leaf512(h,(X),(LX),(Y),(LY),(Z),(LZ)); } while(0)
wg_schain4(h,R4,S2,S3,M3,ldc,A,lda);
wg_bfuse_child4<false>(h,R2,R1,R5,M4,ldc,B,ldb);
PROD2(R4,R2,R3,h,h,h);
/* Q3 already resides in M4; R4 becomes product storage after S1 dies. */
PROD2(S2,R1,R2,h,h,h);
PROD2(S3,R5,R1,h,h,h);
PROD2(A22,M4,R4,lda,ldc,h);
PROD2(M3,B22,R5,ldc,ldb,h);
PROD2(A11,B11,M1,lda,ldb,ldc);
PROD2(A12,B21,M2,lda,ldb,ldc);
#undef PROD2
wg_combine2_stride4<false>(h,C,ldc,M1,M2,R5,h,R4,h,R3,R2,R1);
}


static void winograd_child_N(int n, const long long *A, int lda, const long long *B, int ldb,
long long *C, int ldc) {
const int h=n/2; const size_t sg=(size_t)h*(size_t)(h+8);
long long *M1=C,*M2=C+h,*M3=C+(size_t)h*ldc,*M4=M3+h;
long long *R1=wg_buf2,*R2=R1+sg+512,*R3=R2+sg+512,*R4=R3+sg+512,*R5=R4+sg+512;
long long *S2=wg_buf2_s2,*S3=S2+sg+512;
const long long *A11=A,*A12=A+h,*A21=A+(size_t)h*lda,*A22=A21+h;
const long long *B11=B,*B12=B+h,*B21=B+(size_t)h*ldb,*B22=B21+h;
#define PROD2(X,Y,Z,LX,LY,LZ) do { winograd_grandchild(h,(X),(LX),(Y),(LY),(Z),(LZ)); } while(0)
wg_schain4(h,R4,S2,S3,M3,ldc,A,lda);
wg_bfuse_child4<true>(h,R2,R1,R5,M4,ldc,B,ldb);
PROD2(R4,R2,R3,h,h,h);
/* Q3 already resides in M4; R4 becomes product storage after S1 dies. */
PROD2(S2,R1,R2,h,h,h);
PROD2(S3,R5,R1,h,h,h);
PROD2(A22,M4,R4,lda,ldc,h);
PROD2(M3,B22,R5,ldc,ldb,h);
PROD2(A11,B11,M1,lda,ldb,ldc);
PROD2(A12,B21,M2,lda,ldb,ldc);
#undef PROD2
wg_combine2_stride4<true>(h,C,ldc,M1,M2,R5,h,R4,h,R3,R2,R1);
}


/* v9 child: normal B operand; fused B chain (9h^2); same no-alias schedule as child_N. */
static void winograd_child_F(int n, const long long *A, int lda, const long long *B, int ldb,
long long *C, int ldc) {
const int h=n/2; const size_t sg=(size_t)h*(size_t)(h+8);
long long *M1=C,*M2=C+h,*M3=C+(size_t)h*ldc,*M4=M3+h;
long long *R1=wg_buf2,*R2=R1+sg+512,*R3=R2+sg+512,*R4=R3+sg+512,*R5=R4+sg+512;
long long *S2=wg_buf2_s2,*S3=S2+sg+512;
const long long *A11=A,*A12=A+h,*A21=A+(size_t)h*lda,*A22=A21+h;
const long long *B11=B,*B12=B+h,*B21=B+(size_t)h*ldb,*B22=B21+h;
#define PROD2(X,Y,Z,LX,LY,LZ) do { winograd_grandchild(h,(X),(LX),(Y),(LY),(Z),(LZ)); } while(0)
wg_schain4(h,R4,S2,S3,M3,ldc,A,lda);
wg_bfuse_child4<false>(h,R2,R1,R5,M4,ldc,B,ldb);
PROD2(R4,R2,R3,h,h,h);
/* Q3 already resides in M4; R4 becomes product storage after S1 dies. */
PROD2(S2,R1,R2,h,h,h);
PROD2(S3,R5,R1,h,h,h);
PROD2(A22,M4,R4,lda,ldc,h);
PROD2(M3,B22,R5,ldc,ldb,h);
PROD2(A11,B11,M1,lda,ldb,ldc);
PROD2(A12,B21,M2,lda,ldb,ldc);
#undef PROD2
wg_combine2_stride4<false>(h,C,ldc,M1,M2,R5,h,R4,h,R3,R2,R1);
}

static void winograd_top(int n, const long long *A, const long long *B, long long *C) {
const int h=n/2; const size_t sg=(size_t)h*(size_t)(h+8);  
long long *M1=C,*M2=C+h,*M3=C+(size_t)h*n,*M4=M3+h;
long long *M5=wg_buf,*M6=M5+sg+512,*M7=M6+sg+512,*P=M7+sg+512,*Q=P+sg+512;
/* V3 buffer schedule: R1..R5 = M5,M6,M7,P,Q (wg_buf); C21/C22 used as P4/Q4 temps.
   No product output aliases its input. Final homes:
   M1->C11, M2->C12, M4->C22, M3->R1, M5->R5, M6->R4, M7->R2. */
long long *R1=M5,*R2=M6,*R3=M7,*R4=P,*R5=Q;
const long long *A11=A,*A12=A+h,*A21=A+(size_t)h*n,*A22=A21+h;
const long long *B11=B,*B12=B+h,*B21=B+(size_t)h*n,*B22=B21+h;
#define PROD(X,Y,Z,LX,LY,LZ) do { winograd_child(h,(X),(LX),(Y),(LY),(Z),(LZ)); } while(0)
#define PROD_N(X,Y,Z,LX,LY,LZ) do { winograd_child_N(h,(X),(LX),(Y),(LY),(Z),(LZ)); } while(0)
#define PROD_F(X,Y,Z,LX,LY,LZ) do { winograd_child_F(h,(X),(LX),(Y),(LY),(Z),(LZ)); } while(0)
wg_schain4(h,R1,R2,R3,M3,n,A,n); /* All four A transforms, one source pass. */
wg_bfuse_S4(h,R5,h,R4,h,M1,n,M4,n,B21,B11,B12,B22,n);        /* Q1'->R5, Q2'->R4, Q4'->C11(M1) */
PROD_N(R1,R5,M2,h,h,n);                       /* M5 -> C12(M2) */
/* Q3 is already fused into C22; dead S1 slot R1 holds product M4. */                    /* Q3'=S(Q2-B21) -> R1 (P1 dead) */
PROD_N(R2,R4,R5,h,h,h);                       /* M6 -> R5 (Q1 dead) */
PROD_N(A22,M4,R1,n,n,h);                      /* M4 -> C22 */
PROD_N(R3,M1,R2,h,n,h);                       /* M7 -> R2 (Q4 in C11) */
PROD_F(M3,B22,R3,n,n,h);                      /* M3 -> R3 (child_F) */
PROD_F(A11,B11,R4,n,n,h);                     /* M1(product) -> R4 */
PROD_F(A12,B21,M1,n,n,n);                     /* M2(product) -> C11 */
#undef PROD
#undef PROD_N
#undef PROD_F
wg_combine7(h,C,n, R4,h, M1,n, R3,h, R1,h, M2,n, R5,h, R2,h);
}


static inline void advise_huge(void *p,size_t bytes){
uintptr_t a=(uintptr_t)p,e=a+bytes;
uintptr_t h0=(a+2097151u)&~(uintptr_t)2097151u;
uintptr_t h1=e&~(uintptr_t)2097151u;
if(h1>h0) madvise((void*)h0,(size_t)(h1-h0),MADV_HUGEPAGE);
}
__attribute__((constructor)) static void setup_huge_scratch(){

advise_huge(wg_buf,sizeof(wg_buf));
advise_huge(wg_buf2,sizeof(wg_buf2));
advise_huge(wg_buf1,sizeof(wg_buf1));
advise_huge(wg_buf0,sizeof(wg_buf0));
advise_huge(g_scratch,sizeof(g_scratch));
advise_huge(material_A,sizeof(material_A));
advise_huge(material_B,sizeof(material_B));
advise_huge(material_C,sizeof(material_C));
advise_huge(material_D,sizeof(material_D));
advise_huge(Bpanel,sizeof(Bpanel));
}
static_assert(sizeof(long long)==8,"l4z3a4");
void matrix_multiply(int n, const long long *A, const long long *B, long long *C) {
Opd Ao = o1(A, n), Bo = o1(B, n);
if (n <= CUTL || (n & 1)) { leaf(n, &Ao, &Bo, C, n, 0, 0, 0, 0); return; }
if (n == 4096) winograd_top(n, A, B, C);
else mmxR(n, &Ao, &Bo, C, n, 0, g_scratch);
}
#pragma GCC pop_options


static unsigned char ml4be_layout_pad[8u << 20] __attribute__((used, aligned(2097152)));

__attribute__((weak)) int main() { return 0; }

CompilationN/AN/ACompile OKScore: N/A

Testcase #15.04 s361 MB + 812 KBAcceptedScore: 100


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