提交记录 123052


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_cc_v41_260924 mmmc2k. 测测你的8位整数矩阵乘法-2k Accepted 100 53.05 ms 16288 KB C++17 49.45 KB
提交时间 评测时间
2026-10-03 08:01:39 2026-10-03 08:01:42
#pragma GCC optimize("O3")
/* mmmc_k1: int8 GEMM C = A*B mod 256, EXACT, AVX2.
   Split A = A0 + 128*A1  (A0 = A & 0x7F unsigned, A1 = top bit of each byte).
     term1 = sum_k A0[i][k]*B[k][j]      -> vpmaddubsw, no saturation (127*128*2 < 32768)
     term2 = 128*(A1 . Bpar) mod 256     -> GF(2) matmul, 64 bits/word (Bpar = B&1)
   Layout (lanes = columns): accum lane m is column j0+m.
     x = vpbroadcastw of the 2-byte pair A0[i][2p..2p+1]
     y = 32B load from BI[p] at 2*j0 ; BI[p][2j]=B[2p][j], BI[p][2j+1]=B[2p+1][j]
*/
#include <immintrin.h>
#include <xmmintrin.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>

#define AVX2 __attribute__((target("avx2")))
#define NMAX 4096

/* == mmmpad_fleet ARM: SCRATCH ROW-STRIDE PAD ==
   A0b and PBb are PRIVATE scratch, so their row stride is not semantic -- but it is `n`,
   i.e. 4096 B at n=4096, which is EXACTLY the L1 way-period (64 sets x 64 B).  Every row of
   both buffers then maps its line j into set j, on top of C's rows (also `n`) and the mikro's
   two-row window: 6+ streams share one set out of 8 ways.  LDA/LDB pad the two scratch
   strides.  The cell (row i, col j) is still the same value -- only WHERE it lives changes.
   The mikro takes the scratch stride as an argument instead of deriving `A0+n`. */
#ifndef PADA
#define PADA 0
#endif
#define LDA ((int)(2*NMAX + PADA))
#ifndef PADB
#define PADB 0
#endif
#define LDB ((int)(NMAX + PADB))
static int8_t   A0b[(size_t)NMAX*LDA] __attribute__((aligned(64)));
/* BW9: runtime scratch stride, sized to the ACTUAL m (not NMAX) */
static int GLDA = LDA, GLDB = LDB;

static uint64_t A1b[NMAX*NMAX/8]    __attribute__((aligned(64)));
static uint64_t Bpb[NMAX*NMAX/8]    __attribute__((aligned(64)));
static uint64_t Pbb[NMAX*NMAX/8]    __attribute__((aligned(64)));
static uint8_t  PBb[(size_t)NMAX*LDB+256] __attribute__((aligned(64)));

static void generic_mm(int n, const int8_t*A, const int8_t*B, int8_t*C){
  for (int i=0;i<n;i++) for (int j=0;j<n;j++){
    int s=0; for(int k=0;k<n;k++) s += (int)A[(size_t)i*n+k]*(int)B[(size_t)k*n+j];
    C[(size_t)i*n+j]=(int8_t)s;
  }
}

AVX2 static inline __m256i bcast16(const int8_t*p){
  __m256i v; __asm__("vpbroadcastw %1, %0" : "=x"(v) : "m"(*(const short*)p)); return v;
}
AVX2 static inline __m256i packlo8(__m256i a, __m256i b){
  const __m256i m=_mm256_set1_epi16(0x00FF);
  return _mm256_permute4x64_epi64(
    _mm256_packus_epi16(_mm256_and_si256(a,m), _mm256_and_si256(b,m)), 0xD8);
}

/* build_A0() DELETED by lane CH3: dead, and its A0b stride is the pre-duplication one. */
AVX2 static void build_A1bits(int n, const int8_t*A){
  int W=n/64;
  for (int i=0;i<n;i++){
    const int8_t*row=A+(size_t)i*n; uint64_t*w=A1b+(size_t)i*W;
    for (int k=0;k<n;k+=64){
      uint32_t lo=(uint32_t)_mm256_movemask_epi8(_mm256_load_si256((const __m256i*)(row+k)));
      uint32_t hi=(uint32_t)_mm256_movemask_epi8(_mm256_load_si256((const __m256i*)(row+k+32)));
      w[k>>6]=(uint64_t)lo|((uint64_t)hi<<32);
    }
  }
}
AVX2 static void build_Bpbits(int n, const int8_t*B){
  const __m256i one=_mm256_set1_epi8(1);
  int W=n/64;
  for (int k=0;k<n;k++){
    const int8_t*row=B+(size_t)k*n; uint64_t*w=Bpb+(size_t)k*W;
    for (int j=0;j<n;j+=64){
      __m256i a=_mm256_slli_epi16(_mm256_and_si256(_mm256_load_si256((const __m256i*)(row+j)),one),7);
      __m256i b=_mm256_slli_epi16(_mm256_and_si256(_mm256_load_si256((const __m256i*)(row+j+32)),one),7);
      uint32_t lo=(uint32_t)_mm256_movemask_epi8(a);
      uint32_t hi=(uint32_t)_mm256_movemask_epi8(b);
      w[j>>6]=(uint64_t)lo|((uint64_t)hi<<32);
    }
  }
}

/* P[i] = XOR of Bp[k] over k with A1[i][k] set.  NY = n/256 ymm per row. */
AVX2 static void corr_bits(int n){
  int W=n/64, NY=W>>2;
  for (int i=0;i<n;i++){
    __m256i acc[16];
    for(int t=0;t<NY;t++) acc[t]=_mm256_setzero_si256();
    const uint64_t*row=A1b+(size_t)i*W;
    for(int w=0;w<W;w++){
      uint64_t b=row[w];
      while(b){
        int t=__builtin_ctzll(b); b&=b-1;
        const uint64_t*br=Bpb+(size_t)(w*64+t)*W;
        for(int q=0;q<NY;q++)
          acc[q]=_mm256_xor_si256(acc[q],_mm256_load_si256((const __m256i*)(br+4*q)));
      }
    }
    uint64_t*o=Pbb+(size_t)i*W;
    for(int q=0;q<NY;q++) _mm256_store_si256((__m256i*)(o+4*q),acc[q]);
  }
}

static uint64_t A1T[NMAX*NMAX/8] __attribute__((aligned(64)));
AVX2 static void transpose64(uint64_t *a){
  int j,k; uint64_t m,t;
  for (j=32,m=0xFFFFFFFF00000000ULL; j; j>>=1, m^=m>>j)
    for (k=0;k<64;k=(k+j+1)&~j){
      t=(a[k]^(a[k+j]<<j))&m;
      a[k]^=t; a[k+j]^=(t>>j);
    }
}
AVX2 static void build_A1T(int n){
  int W=n/64;
  for (int kb=0; kb<n; kb+=64)
    for (int ib=0; ib<n; ib+=64){
      uint64_t blk[64];
      for (int i=0;i<64;i++) blk[i]=A1b[(size_t)(ib+i)*W+(kb>>6)];
      transpose64(blk);
      for (int k=0;k<64;k++) A1T[(size_t)(kb+k)*W+(ib>>6)]=blk[k];
    }
}

/* P[i][j] = XOR over k with A1[i][k] set of Bp[k][j].
   Per-output-row bit scan (dense 64-bit words -> predictable), K-BLOCKED so the
   Bp slice stays in L2.  P accumulated in memory across k-blocks. */
AVX2 static void corr_pass3(int n){
  int W=n/64, NY=W>>2;
  memset(Pbb,0,(size_t)n*W*8);
  const int KB=256;
  for (int kb=0; kb<n; kb+=KB){
    int w0=kb>>6, w1=w0+(KB>>6);
    for (int i=0;i<n;i++){
      __m256i acc[16];
      for (int q=0;q<NY;q++) acc[q]=_mm256_setzero_si256();
      const uint64_t*row=A1b+(size_t)i*W;
      for (int w=w0;w<w1;w++){
        uint64_t b=row[w];
        while(b){
          int t=__builtin_ctzll(b); b&=b-1;
          const uint64_t*br=Bpb+(size_t)(w*64+t)*W;
          for (int q=0;q<NY;q++) acc[q]=_mm256_xor_si256(acc[q],_mm256_load_si256((const __m256i*)(br+4*q)));
        }
      }
      uint64_t*o=Pbb+(size_t)i*W;
      for (int q=0;q<NY;q++){
        __m256i*po=(__m256i*)(o+4*q);
        _mm256_store_si256(po,_mm256_xor_si256(_mm256_load_si256((const __m256i*)po),acc[q]));
      }
    }
  }
}


/* specialized for n=4096 (W=64, NY=16): fully unrolled XOR loops */
/* corr16(): fully hand-written per-row GF(2) accumulate. Bit-identical output. */
#define AVX2BMI __attribute__((target("avx2,bmi")))

AVX2BMI static void corr16(void){
  const int n=4096, W=64;
  memset(Pbb,0,(size_t)n*W*8);
  const int KB=64;
  for (int kb=0; kb<n; kb+=KB){
    int w0=kb>>6;
    const char *bp0=(const char*)Bpb+(size_t)w0*32768;
    const char *bp1=bp0; (void)bp1;
    for (int i=0;i<n;i++){
      const uint64_t*row=A1b+(size_t)i*W+w0;
      uint64_t b0=row[0], b1=0;
      uint64_t *o=Pbb+(size_t)i*W;
      asm volatile(
        "vpxor %%xmm0,%%xmm0,%%xmm0\n\t"
        "vpxor %%xmm1,%%xmm1,%%xmm1\n\t"
        "vpxor %%xmm2,%%xmm2,%%xmm2\n\t"
        "vpxor %%xmm3,%%xmm3,%%xmm3\n\t"
        "vpxor %%xmm4,%%xmm4,%%xmm4\n\t"
        "vpxor %%xmm5,%%xmm5,%%xmm5\n\t"
        "vpxor %%xmm6,%%xmm6,%%xmm6\n\t"
        "vpxor %%xmm7,%%xmm7,%%xmm7\n\t"
        "vpxor %%xmm8,%%xmm8,%%xmm8\n\t"
        "vpxor %%xmm9,%%xmm9,%%xmm9\n\t"
        "vpxor %%xmm10,%%xmm10,%%xmm10\n\t"
        "vpxor %%xmm11,%%xmm11,%%xmm11\n\t"
        "vpxor %%xmm12,%%xmm12,%%xmm12\n\t"
        "vpxor %%xmm13,%%xmm13,%%xmm13\n\t"
        "vpxor %%xmm14,%%xmm14,%%xmm14\n\t"
        "vpxor %%xmm15,%%xmm15,%%xmm15\n\t"
        "testq %[b0], %[b0]\n\t"
        "jz 3%=f\n\t"
        "1%=:\n\t"
        "tzcntq %[b0], %%r11\n\t"
        "shlq $9, %%r11\n\t"
        "addq %[bp0], %%r11\n\t"
        "vpxor 0(%%r11), %%ymm0, %%ymm0\n\t"
        "vpxor 32(%%r11), %%ymm1, %%ymm1\n\t"
        "vpxor 64(%%r11), %%ymm2, %%ymm2\n\t"
        "vpxor 96(%%r11), %%ymm3, %%ymm3\n\t"
        "vpxor 128(%%r11), %%ymm4, %%ymm4\n\t"
        "vpxor 160(%%r11), %%ymm5, %%ymm5\n\t"
        "vpxor 192(%%r11), %%ymm6, %%ymm6\n\t"
        "vpxor 224(%%r11), %%ymm7, %%ymm7\n\t"
        "vpxor 256(%%r11), %%ymm8, %%ymm8\n\t"
        "vpxor 288(%%r11), %%ymm9, %%ymm9\n\t"
        "vpxor 320(%%r11), %%ymm10, %%ymm10\n\t"
        "vpxor 352(%%r11), %%ymm11, %%ymm11\n\t"
        "vpxor 384(%%r11), %%ymm12, %%ymm12\n\t"
        "vpxor 416(%%r11), %%ymm13, %%ymm13\n\t"
        "vpxor 448(%%r11), %%ymm14, %%ymm14\n\t"
        "vpxor 480(%%r11), %%ymm15, %%ymm15\n\t"
        "blsrq %[b0], %[b0]\n\t"
        "jnz 1%=b\n\t"
        "3%=:\n\t"
        "testq %[b1], %[b1]\n\t"
        "jz 4%=f\n\t"
        "2%=:\n\t"
        "tzcntq %[b1], %%r11\n\t"
        "shlq $9, %%r11\n\t"
        "addq %[bp1], %%r11\n\t"
        "vpxor 0(%%r11), %%ymm0, %%ymm0\n\t"
        "vpxor 32(%%r11), %%ymm1, %%ymm1\n\t"
        "vpxor 64(%%r11), %%ymm2, %%ymm2\n\t"
        "vpxor 96(%%r11), %%ymm3, %%ymm3\n\t"
        "vpxor 128(%%r11), %%ymm4, %%ymm4\n\t"
        "vpxor 160(%%r11), %%ymm5, %%ymm5\n\t"
        "vpxor 192(%%r11), %%ymm6, %%ymm6\n\t"
        "vpxor 224(%%r11), %%ymm7, %%ymm7\n\t"
        "vpxor 256(%%r11), %%ymm8, %%ymm8\n\t"
        "vpxor 288(%%r11), %%ymm9, %%ymm9\n\t"
        "vpxor 320(%%r11), %%ymm10, %%ymm10\n\t"
        "vpxor 352(%%r11), %%ymm11, %%ymm11\n\t"
        "vpxor 384(%%r11), %%ymm12, %%ymm12\n\t"
        "vpxor 416(%%r11), %%ymm13, %%ymm13\n\t"
        "vpxor 448(%%r11), %%ymm14, %%ymm14\n\t"
        "vpxor 480(%%r11), %%ymm15, %%ymm15\n\t"
        "blsrq %[b1], %[b1]\n\t"
        "jnz 2%=b\n\t"
        "4%=:\n\t"
        "vpxor   0(%[o]), %%ymm0, %%ymm0\n\t"
        "vmovdqu %%ymm0, 0(%[o])\n\t"
        "vpxor   32(%[o]), %%ymm1, %%ymm1\n\t"
        "vmovdqu %%ymm1, 32(%[o])\n\t"
        "vpxor   64(%[o]), %%ymm2, %%ymm2\n\t"
        "vmovdqu %%ymm2, 64(%[o])\n\t"
        "vpxor   96(%[o]), %%ymm3, %%ymm3\n\t"
        "vmovdqu %%ymm3, 96(%[o])\n\t"
        "vpxor   128(%[o]), %%ymm4, %%ymm4\n\t"
        "vmovdqu %%ymm4, 128(%[o])\n\t"
        "vpxor   160(%[o]), %%ymm5, %%ymm5\n\t"
        "vmovdqu %%ymm5, 160(%[o])\n\t"
        "vpxor   192(%[o]), %%ymm6, %%ymm6\n\t"
        "vmovdqu %%ymm6, 192(%[o])\n\t"
        "vpxor   224(%[o]), %%ymm7, %%ymm7\n\t"
        "vmovdqu %%ymm7, 224(%[o])\n\t"
        "vpxor   256(%[o]), %%ymm8, %%ymm8\n\t"
        "vmovdqu %%ymm8, 256(%[o])\n\t"
        "vpxor   288(%[o]), %%ymm9, %%ymm9\n\t"
        "vmovdqu %%ymm9, 288(%[o])\n\t"
        "vpxor   320(%[o]), %%ymm10, %%ymm10\n\t"
        "vmovdqu %%ymm10, 320(%[o])\n\t"
        "vpxor   352(%[o]), %%ymm11, %%ymm11\n\t"
        "vmovdqu %%ymm11, 352(%[o])\n\t"
        "vpxor   384(%[o]), %%ymm12, %%ymm12\n\t"
        "vmovdqu %%ymm12, 384(%[o])\n\t"
        "vpxor   416(%[o]), %%ymm13, %%ymm13\n\t"
        "vmovdqu %%ymm13, 416(%[o])\n\t"
        "vpxor   448(%[o]), %%ymm14, %%ymm14\n\t"
        "vmovdqu %%ymm14, 448(%[o])\n\t"
        "vpxor   480(%[o]), %%ymm15, %%ymm15\n\t"
        "vmovdqu %%ymm15, 480(%[o])\n\t"
        : [b0]"+r"(b0), [b1]"+r"(b1)
        : [bp0]"r"(bp0), [bp1]"r"(bp1), [o]"r"(o)
        : "r11","cc","memory","ymm0","ymm1","ymm2","ymm3","ymm4","ymm5","ymm6","ymm7","ymm8","ymm9","ymm10","ymm11","ymm12","ymm13","ymm14","ymm15");
    }
  }
}

static void expand_bits(int n){
  static uint8_t T[256*8]; static int ti=0;
  if(!ti){ for(int v=0;v<256;v++) for(int b=0;b<8;b++) T[v*8+b]=((v>>b)&1)?0x80:0x00; ti=1; }
  int W=n/64;
  for(int i=0;i<n;i++){
    const uint64_t*w=Pbb+(size_t)i*W; uint8_t*o=PBb+(size_t)i*GLDB;
    for(int q=0;q<W;q++){
      uint64_t v=w[q];
      for(int s=0;s<8;s++) memcpy(o+(q*8+s)*8, T+(((uint8_t)(v>>(8*s)))*8), 8);
    }
  }
}

#define NIB 2
#define NJ 4
static const int16_t W0FF[16] __attribute__((aligned(32))) =
  {0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,
   0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF};


static int8_t BI3b[NMAX*NMAX] __attribute__((aligned(64)));
AVX2 static void build_BI3(int n, const int8_t*B){
  int ng=n/64;
  for (int p=0;p<n/2;p++){
    const int8_t *r0=B+(size_t)(2*p)*n, *r1=r0+n;
    for (int g=0;g<ng;g++){
      const int8_t *a=r0+64*g, *b=r1+64*g;
      int8_t *o=BI3b+((size_t)g*(n/2)+p)*128;
      for (int t=0;t<64;t+=32){
        __m256i va=_mm256_load_si256((const __m256i*)(a+t));
        __m256i vb=_mm256_load_si256((const __m256i*)(b+t));
        __m256i lo=_mm256_unpacklo_epi8(va,vb), hi=_mm256_unpackhi_epi8(va,vb);
        _mm256_store_si256((__m256i*)(o+2*t),    _mm256_permute2x128_si256(lo,hi,0x20));
        _mm256_store_si256((__m256i*)(o+2*t+32), _mm256_permute2x128_si256(lo,hi,0x31));
      }
    }
  }
}
AVX2 static void mikro_u4(int n,const int8_t*A0,const int8_t*BI,int8_t*C,const uint8_t*PB,int jb,int lda,int ldb){
  const int8_t *x0=A0;
  long nn=(long)n;
  const int8_t *x1=A0+lda;
  const int8_t *bib=BI+(long)(n>>3)*512; long bidx=-((long)(n>>3)*512);
  int8_t *C0=C+jb, *C1=C0+n;
  const uint8_t *PB0=PB+jb, *PB1=PB0+ldb;
  asm volatile(
    "vpxor %%xmm8,%%xmm8,%%xmm8\n\t"
    "vpxor %%xmm9,%%xmm9,%%xmm9\n\t"
    "vpxor %%xmm10,%%xmm10,%%xmm10\n\t"
    "vpxor %%xmm11,%%xmm11,%%xmm11\n\t"
    "vpxor %%xmm12,%%xmm12,%%xmm12\n\t"
    "vpxor %%xmm13,%%xmm13,%%xmm13\n\t"
    "vpxor %%xmm14,%%xmm14,%%xmm14\n\t"
    "vpxor %%xmm15,%%xmm15,%%xmm15\n\t"
    ".p2align 5\n\t"
    "1:\n\t"
    "vpbroadcastd 0(%[x0]), %%ymm0\n\t"
    "vpbroadcastd 0(%[x1]), %%ymm1\n\t"
    "vmovdqa 0(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm8, %%ymm8\n\t"
    "vpaddw %%ymm6, %%ymm12, %%ymm12\n\t"
    "vmovdqa 32(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm9, %%ymm9\n\t"
    "vpaddw %%ymm6, %%ymm13, %%ymm13\n\t"
    "vmovdqa 64(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm10, %%ymm10\n\t"
    "vpaddw %%ymm6, %%ymm14, %%ymm14\n\t"
    "vmovdqa 96(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm11, %%ymm11\n\t"
    "vpaddw %%ymm6, %%ymm15, %%ymm15\n\t"
    "vpbroadcastd 4(%[x0]), %%ymm0\n\t"
    "vpbroadcastd 4(%[x1]), %%ymm1\n\t"
    "vmovdqa 128(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm8, %%ymm8\n\t"
    "vpaddw %%ymm6, %%ymm12, %%ymm12\n\t"
    "vmovdqa 160(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm9, %%ymm9\n\t"
    "vpaddw %%ymm6, %%ymm13, %%ymm13\n\t"
    "vmovdqa 192(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm10, %%ymm10\n\t"
    "vpaddw %%ymm6, %%ymm14, %%ymm14\n\t"
    "vmovdqa 224(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm11, %%ymm11\n\t"
    "vpaddw %%ymm6, %%ymm15, %%ymm15\n\t"
    "vpbroadcastd 8(%[x0]), %%ymm0\n\t"
    "vpbroadcastd 8(%[x1]), %%ymm1\n\t"
    "vmovdqa 256(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm8, %%ymm8\n\t"
    "vpaddw %%ymm6, %%ymm12, %%ymm12\n\t"
    "vmovdqa 288(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm9, %%ymm9\n\t"
    "vpaddw %%ymm6, %%ymm13, %%ymm13\n\t"
    "vmovdqa 320(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm10, %%ymm10\n\t"
    "vpaddw %%ymm6, %%ymm14, %%ymm14\n\t"
    "vmovdqa 352(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm11, %%ymm11\n\t"
    "vpaddw %%ymm6, %%ymm15, %%ymm15\n\t"
    "vpbroadcastd 12(%[x0]), %%ymm0\n\t"
    "vpbroadcastd 12(%[x1]), %%ymm1\n\t"
    "vmovdqa 384(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm8, %%ymm8\n\t"
    "vpaddw %%ymm6, %%ymm12, %%ymm12\n\t"
    "vmovdqa 416(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm9, %%ymm9\n\t"
    "vpaddw %%ymm6, %%ymm13, %%ymm13\n\t"
    "vmovdqa 448(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm10, %%ymm10\n\t"
    "vpaddw %%ymm6, %%ymm14, %%ymm14\n\t"
    "vmovdqa 480(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm11, %%ymm11\n\t"
    "vpaddw %%ymm6, %%ymm15, %%ymm15\n\t"
    "addq $16, %[x0]\n\t"
    "addq $16, %[x1]\n\t"
    "addq $512, %[bidx]\n\t"
    "jnz 1b\n\t"
    "vpand %[mask], %%ymm8, %%ymm2\n\t"
    "vpand %[mask], %%ymm9, %%ymm3\n\t"
    "vpackuswb %%ymm3, %%ymm2, %%ymm2\n\t"
    "vpermq $0xD8, %%ymm2, %%ymm2\n\t"
    "vpxor 0(%[PB0]), %%ymm2, %%ymm2\n\t"
    "vmovntdq %%ymm2, 0(%[C0])\n\t"
    "vpand %[mask], %%ymm10, %%ymm2\n\t"
    "vpand %[mask], %%ymm11, %%ymm3\n\t"
    "vpackuswb %%ymm3, %%ymm2, %%ymm2\n\t"
    "vpermq $0xD8, %%ymm2, %%ymm2\n\t"
    "vpxor 32(%[PB0]), %%ymm2, %%ymm2\n\t"
    "vmovntdq %%ymm2, 32(%[C0])\n\t"
    "vpand %[mask], %%ymm12, %%ymm2\n\t"
    "vpand %[mask], %%ymm13, %%ymm3\n\t"
    "vpackuswb %%ymm3, %%ymm2, %%ymm2\n\t"
    "vpermq $0xD8, %%ymm2, %%ymm2\n\t"
    "vpxor 0(%[PB1]), %%ymm2, %%ymm2\n\t"
    "vmovntdq %%ymm2, 0(%[C1])\n\t"
    "vpand %[mask], %%ymm14, %%ymm2\n\t"
    "vpand %[mask], %%ymm15, %%ymm3\n\t"
    "vpackuswb %%ymm3, %%ymm2, %%ymm2\n\t"
    "vpermq $0xD8, %%ymm2, %%ymm2\n\t"
    "vpxor 32(%[PB1]), %%ymm2, %%ymm2\n\t"
    "vmovntdq %%ymm2, 32(%[C1])\n\t"
    : [x0]"+r"(x0), [bidx]"+r"(bidx), [x1]"+r"(x1)
    : [C0]"r"(C0), [C1]"r"(C1), [PB0]"r"(PB0), [PB1]"r"(PB1), [nn]"r"(nn), [mask]"m"(W0FF), [bib]"r"(bib)
    : "ymm0","ymm1","ymm2","ymm3","ymm4","ymm5","ymm6","ymm8","ymm9","ymm10","ymm11","ymm12","ymm13","ymm14","ymm15","cc","memory");
}

AVX2 static void mikro_u4r(int n,const int8_t*A0,const int8_t*BI,int8_t*C,const uint8_t*PB,int jb,int lda,int ldb){
  const int8_t *x0=A0;
  long nn=(long)n;
  const int8_t *x1=A0+lda;
  const int8_t *bib=BI;  /* R1: slice START -- see mk_rev.py */ long bidx=((long)(n>>3)*512)-512;  /* R1: start at the LAST 512-byte chunk */
  int8_t *C0=C+jb, *C1=C0+n;
  const uint8_t *PB0=PB+jb, *PB1=PB0+ldb;
  asm volatile(
    "vpxor %%xmm8,%%xmm8,%%xmm8\n\t"
    "vpxor %%xmm9,%%xmm9,%%xmm9\n\t"
    "vpxor %%xmm10,%%xmm10,%%xmm10\n\t"
    "vpxor %%xmm11,%%xmm11,%%xmm11\n\t"
    "vpxor %%xmm12,%%xmm12,%%xmm12\n\t"
    "vpxor %%xmm13,%%xmm13,%%xmm13\n\t"
    "vpxor %%xmm14,%%xmm14,%%xmm14\n\t"
    "vpxor %%xmm15,%%xmm15,%%xmm15\n\t"
    ".p2align 5\n\t"
    "1:\n\t"
    "vpbroadcastd 0(%[x0]), %%ymm0\n\t"
    "vpbroadcastd 0(%[x1]), %%ymm1\n\t"
    "vmovdqa 0(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm8, %%ymm8\n\t"
    "vpaddw %%ymm6, %%ymm12, %%ymm12\n\t"
    "vmovdqa 32(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm9, %%ymm9\n\t"
    "vpaddw %%ymm6, %%ymm13, %%ymm13\n\t"
    "vmovdqa 64(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm10, %%ymm10\n\t"
    "vpaddw %%ymm6, %%ymm14, %%ymm14\n\t"
    "vmovdqa 96(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm11, %%ymm11\n\t"
    "vpaddw %%ymm6, %%ymm15, %%ymm15\n\t"
    "vpbroadcastd 4(%[x0]), %%ymm0\n\t"
    "vpbroadcastd 4(%[x1]), %%ymm1\n\t"
    "vmovdqa 128(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm8, %%ymm8\n\t"
    "vpaddw %%ymm6, %%ymm12, %%ymm12\n\t"
    "vmovdqa 160(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm9, %%ymm9\n\t"
    "vpaddw %%ymm6, %%ymm13, %%ymm13\n\t"
    "vmovdqa 192(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm10, %%ymm10\n\t"
    "vpaddw %%ymm6, %%ymm14, %%ymm14\n\t"
    "vmovdqa 224(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm11, %%ymm11\n\t"
    "vpaddw %%ymm6, %%ymm15, %%ymm15\n\t"
    "vpbroadcastd 8(%[x0]), %%ymm0\n\t"
    "vpbroadcastd 8(%[x1]), %%ymm1\n\t"
    "vmovdqa 256(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm8, %%ymm8\n\t"
    "vpaddw %%ymm6, %%ymm12, %%ymm12\n\t"
    "vmovdqa 288(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm9, %%ymm9\n\t"
    "vpaddw %%ymm6, %%ymm13, %%ymm13\n\t"
    "vmovdqa 320(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm10, %%ymm10\n\t"
    "vpaddw %%ymm6, %%ymm14, %%ymm14\n\t"
    "vmovdqa 352(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm11, %%ymm11\n\t"
    "vpaddw %%ymm6, %%ymm15, %%ymm15\n\t"
    "vpbroadcastd 12(%[x0]), %%ymm0\n\t"
    "vpbroadcastd 12(%[x1]), %%ymm1\n\t"
    "vmovdqa 384(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm8, %%ymm8\n\t"
    "vpaddw %%ymm6, %%ymm12, %%ymm12\n\t"
    "vmovdqa 416(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm9, %%ymm9\n\t"
    "vpaddw %%ymm6, %%ymm13, %%ymm13\n\t"
    "vmovdqa 448(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm10, %%ymm10\n\t"
    "vpaddw %%ymm6, %%ymm14, %%ymm14\n\t"
    "vmovdqa 480(%[bib],%[bidx]), %%ymm4\n\t"
    "vpmaddubsw %%ymm4, %%ymm0, %%ymm5\n\t"
    "vpmaddubsw %%ymm4, %%ymm1, %%ymm6\n\t"
    "vpaddw %%ymm5, %%ymm11, %%ymm11\n\t"
    "vpaddw %%ymm6, %%ymm15, %%ymm15\n\t"
    "subq $16, %[x0]\n\t"
    "subq $16, %[x1]\n\t"
    "subq $512, %[bidx]\n\t"
    "jns 1b\n\t"
    "vpand %[mask], %%ymm8, %%ymm2\n\t"
    "vpand %[mask], %%ymm9, %%ymm3\n\t"
    "vpackuswb %%ymm3, %%ymm2, %%ymm2\n\t"
    "vpermq $0xD8, %%ymm2, %%ymm2\n\t"
    "vpxor 0(%[PB0]), %%ymm2, %%ymm2\n\t"
    "vmovntdq %%ymm2, 0(%[C0])\n\t"
    "vpand %[mask], %%ymm10, %%ymm2\n\t"
    "vpand %[mask], %%ymm11, %%ymm3\n\t"
    "vpackuswb %%ymm3, %%ymm2, %%ymm2\n\t"
    "vpermq $0xD8, %%ymm2, %%ymm2\n\t"
    "vpxor 32(%[PB0]), %%ymm2, %%ymm2\n\t"
    "vmovntdq %%ymm2, 32(%[C0])\n\t"
    "vpand %[mask], %%ymm12, %%ymm2\n\t"
    "vpand %[mask], %%ymm13, %%ymm3\n\t"
    "vpackuswb %%ymm3, %%ymm2, %%ymm2\n\t"
    "vpermq $0xD8, %%ymm2, %%ymm2\n\t"
    "vpxor 0(%[PB1]), %%ymm2, %%ymm2\n\t"
    "vmovntdq %%ymm2, 0(%[C1])\n\t"
    "vpand %[mask], %%ymm14, %%ymm2\n\t"
    "vpand %[mask], %%ymm15, %%ymm3\n\t"
    "vpackuswb %%ymm3, %%ymm2, %%ymm2\n\t"
    "vpermq $0xD8, %%ymm2, %%ymm2\n\t"
    "vpxor 32(%[PB1]), %%ymm2, %%ymm2\n\t"
    "vmovntdq %%ymm2, 32(%[C1])\n\t"
    : [x0]"+r"(x0), [bidx]"+r"(bidx), [x1]"+r"(x1)
    : [C0]"r"(C0), [C1]"r"(C1), [PB0]"r"(PB0), [PB1]"r"(PB1), [nn]"r"(nn), [mask]"m"(W0FF), [bib]"r"(bib)
    : "ymm0","ymm1","ymm2","ymm3","ymm4","ymm5","ymm6","ymm8","ymm9","ymm10","ymm11","ymm12","ymm13","ymm14","ymm15","cc","memory");
}

/* FUSED BUILDERS (ported from mmmc2k, pure-n): one pass over A, one over B */
AVX2 static void build_A0A1(int n, const int8_t*A){
  const __m256i m=_mm256_set1_epi8(0x7F);
  int W=n/64;
  for (int i=0;i<n;i++){
    const int8_t*row=A+(size_t)i*n;
    int8_t*dst=A0b+(size_t)i*GLDA;
    uint64_t*w1=A1b+(size_t)i*W;
    for (int k=0;k<n;k+=64){
      __m256i v0=_mm256_load_si256((const __m256i*)(row+k));
      __m256i v1=_mm256_load_si256((const __m256i*)(row+k+32));
      { __m256i _w0=_mm256_and_si256(v0,m), _w1=_mm256_and_si256(v1,m);
        __m256i _l0=_mm256_unpacklo_epi16(_w0,_w0), _h0=_mm256_unpackhi_epi16(_w0,_w0);
        __m256i _l1=_mm256_unpacklo_epi16(_w1,_w1), _h1=_mm256_unpackhi_epi16(_w1,_w1);
        _mm256_store_si256((__m256i*)(dst+2*k),    _mm256_permute2x128_si256(_l0,_h0,0x20));
        _mm256_store_si256((__m256i*)(dst+2*k+32), _mm256_permute2x128_si256(_l0,_h0,0x31));
        _mm256_store_si256((__m256i*)(dst+2*k+64), _mm256_permute2x128_si256(_l1,_h1,0x20));
        _mm256_store_si256((__m256i*)(dst+2*k+96), _mm256_permute2x128_si256(_l1,_h1,0x31)); }
      w1[k>>6]=(uint64_t)(uint32_t)_mm256_movemask_epi8(v0)
              |((uint64_t)(uint32_t)_mm256_movemask_epi8(v1)<<32);
    }
  }
}

AVX2 static void build_BI3Bp(int n, const int8_t*B){
  const __m256i one=_mm256_set1_epi8(1);
  int ng=n/64, W=n/64;
  for (int p=0;p<n/2;p++){
    const int8_t *r0=B+(size_t)(2*p)*n, *r1=r0+n;
    uint64_t *w0p=Bpb+(size_t)(2*p)*W, *w1p=Bpb+(size_t)(2*p+1)*W;
    for (int g=0;g<ng;g++){
      const int8_t *a=r0+64*g, *b=r1+64*g;
      int8_t *o=BI3b+((size_t)g*(n/2)+p)*128;
      for (int t=0;t<64;t+=32){
        __m256i va=_mm256_load_si256((const __m256i*)(a+t));
        __m256i vb=_mm256_load_si256((const __m256i*)(b+t));
        __m256i lo=_mm256_unpacklo_epi8(va,vb), hi=_mm256_unpackhi_epi8(va,vb);
        _mm256_store_si256((__m256i*)(o+2*t),    _mm256_permute2x128_si256(lo,hi,0x20));
        _mm256_store_si256((__m256i*)(o+2*t+32), _mm256_permute2x128_si256(lo,hi,0x31));
        uint32_t m0=(uint32_t)_mm256_movemask_epi8(_mm256_slli_epi16(_mm256_and_si256(va,one),7));
        uint32_t m1=(uint32_t)_mm256_movemask_epi8(_mm256_slli_epi16(_mm256_and_si256(vb,one),7));
        if(t==0)      { w0p[g]=(uint64_t)m0;      w1p[g]=(uint64_t)m1; }
        else          { w0p[g]|=(uint64_t)m0<<32; w1p[g]|=(uint64_t)m1<<32; }
      }
    }
  }
}



/* ================= STRASSEN (exact over Z/256) =================
   Every coefficient is +-1 and there is no division, so the identities hold in ANY commutative
   ring; int8 arithmetic mod 256 is exactly that ring.  The case table and the combine
   coefficients are GENERATED from tables that mkstrassen4k.py's self-check brute-forces over
   Z/256 before this file is written.
   ============================================================== */
#define SM 2048
static int8_t SA[SM*SM]     __attribute__((aligned(64)));
static int8_t SB[SM*SM]     __attribute__((aligned(64)));
static int8_t MMS[7][1024*1024+256] __attribute__((aligned(64)));

/* ============ FUSED QUADRANT PACKERS (--fuse) ============
   The unfused path builds S2A/S2B with blk() and hands them to build_A0A1/build_BI3Bp, which
   read them straight back: 2 MB written and 2 MB re-read per sub-product, x49.  These write the
   PACKED forms DIRECTLY from the parent's quadrants.  Every stored value is identical by
   construction, so this is a pure traffic deletion, not a re-derivation.
   buildA_q/buildB_q(int h,int n,X,r0,c0,Y,r1,c1,op)  ==  pack(X quad op Y quad)
   ========================================================= */
AVX2 static void buildA_q(int h,int n,const int8_t*X,int r0,int c0,
                          const int8_t*Y,int r1,int c1,int op){
  const __m256i mx=_mm256_set1_epi8(0x7F);
  int W=h/64;
  for (int i=0;i<h;i++){
    const int8_t*xa=X+(size_t)(r0+i)*n+c0, *ya=Y+(size_t)(r1+i)*n+c1;
    int8_t*dst=A0b+(size_t)i*GLDA;
    uint64_t*w1=A1b+(size_t)i*W;
    for (int k=0;k<h;k+=64){
      __m256i v0=_mm256_load_si256((const __m256i*)(xa+k));
      __m256i v1=_mm256_load_si256((const __m256i*)(xa+k+32));
      if (op){ __m256i u0=_mm256_load_si256((const __m256i*)(ya+k));
               __m256i u1=_mm256_load_si256((const __m256i*)(ya+k+32));
               if(op==1){ v0=_mm256_add_epi8(v0,u0); v1=_mm256_add_epi8(v1,u1); }
               else     { v0=_mm256_sub_epi8(v0,u0); v1=_mm256_sub_epi8(v1,u1); } }
      { __m256i _w0=_mm256_and_si256(v0,mx), _w1=_mm256_and_si256(v1,mx);
        __m256i _l0=_mm256_unpacklo_epi16(_w0,_w0), _h0=_mm256_unpackhi_epi16(_w0,_w0);
        __m256i _l1=_mm256_unpacklo_epi16(_w1,_w1), _h1=_mm256_unpackhi_epi16(_w1,_w1);
        _mm256_store_si256((__m256i*)(dst+2*k),    _mm256_permute2x128_si256(_l0,_h0,0x20));
        _mm256_store_si256((__m256i*)(dst+2*k+32), _mm256_permute2x128_si256(_l0,_h0,0x31));
        _mm256_store_si256((__m256i*)(dst+2*k+64), _mm256_permute2x128_si256(_l1,_h1,0x20));
        _mm256_store_si256((__m256i*)(dst+2*k+96), _mm256_permute2x128_si256(_l1,_h1,0x31)); }
      w1[k>>6]=(uint64_t)(uint32_t)_mm256_movemask_epi8(v0)
              |((uint64_t)(uint32_t)_mm256_movemask_epi8(v1)<<32);
    }
  }
}
AVX2 static void buildB_q(int h,int n,const int8_t*X,int r0,int c0,
                          const int8_t*Y,int r1,int c1,int op){
  const __m256i one=_mm256_set1_epi8(1);
  int ng=h/64, W=h/64;
  for (int p=0;p<h/2;p++){
    const int8_t *ra=X+(size_t)(r0+2*p)*n+c0,   *rb=X+(size_t)(r0+2*p+1)*n+c0;
    const int8_t *sa=Y+(size_t)(r1+2*p)*n+c1,   *sb=Y+(size_t)(r1+2*p+1)*n+c1;
    uint64_t *w0p=Bpb+(size_t)(2*p)*W, *w1p=Bpb+(size_t)(2*p+1)*W;
    for (int g=0;g<ng;g++){
      for (int t=0;t<64;t+=32){
        __m256i va=_mm256_load_si256((const __m256i*)(ra+64*g+t));
        __m256i vb=_mm256_load_si256((const __m256i*)(rb+64*g+t));
        if (op){ __m256i pa=_mm256_load_si256((const __m256i*)(sa+64*g+t));
                 __m256i pb=_mm256_load_si256((const __m256i*)(sb+64*g+t));
                 if(op==1){ va=_mm256_add_epi8(va,pa); vb=_mm256_add_epi8(vb,pb); }
                 else     { va=_mm256_sub_epi8(va,pa); vb=_mm256_sub_epi8(vb,pb); } }
        __m256i lo=_mm256_unpacklo_epi8(va,vb), hi=_mm256_unpackhi_epi8(va,vb);
        int8_t *o=BI3b+((size_t)g*(h/2)+p)*128;
        _mm256_store_si256((__m256i*)(o+2*t),    _mm256_permute2x128_si256(lo,hi,0x20));
        _mm256_store_si256((__m256i*)(o+2*t+32), _mm256_permute2x128_si256(lo,hi,0x31));
        uint32_t mm0=(uint32_t)_mm256_movemask_epi8(_mm256_slli_epi16(_mm256_and_si256(va,one),7));
        uint32_t mm1=(uint32_t)_mm256_movemask_epi8(_mm256_slli_epi16(_mm256_and_si256(vb,one),7));
        if(t==0){ w0p[g]=(uint64_t)mm0;      w1p[g]=(uint64_t)mm1; }
        else    { w0p[g]|=(uint64_t)mm0<<32; w1p[g]|=(uint64_t)mm1<<32; }
      }
    }
  }
}

/* ---- LEVEL 2 scratch: the m x m sub-product is itself Strassen-decomposed into 7 of h=m/2 ---- */
static int8_t S2M[7][512*512+256]  __attribute__((aligned(64)));


/* Cblk += sum_k s_k * M_k  (up to 4 terms; NULL skips a term).  dst stride is `n`, block is m x m. */
AVX2 static void cmb(int8_t*C,int n,int r0,int c0,int m,
                     const int8_t*M0,int s0,const int8_t*M1,int s1,
                     const int8_t*M2,int s2,const int8_t*M3,int s3){
  for (int i=0;i<m;i++){
    int8_t *d=C+(size_t)(r0+i)*n+c0;
    const int8_t *p0=M0?M0+(size_t)i*m:0, *p1=M1?M1+(size_t)i*m:0;
    const int8_t *p2=M2?M2+(size_t)i*m:0, *p3=M3?M3+(size_t)i*m:0;
    for (int j=0;j<m;j+=32){
      __m256i v;
      if (p0){ __m256i t=_mm256_load_si256((const __m256i*)(p0+j));
               v = s0>0?t:_mm256_sub_epi8(_mm256_setzero_si256(),t); }
      else    v = _mm256_setzero_si256();
      if (p1){ __m256i t=_mm256_load_si256((const __m256i*)(p1+j));
               v = _mm256_add_epi8(v, s1>0?t:_mm256_sub_epi8(_mm256_setzero_si256(),t)); }
      if (p2){ __m256i t=_mm256_load_si256((const __m256i*)(p2+j));
               v = _mm256_add_epi8(v, s2>0?t:_mm256_sub_epi8(_mm256_setzero_si256(),t)); }
      if (p3){ __m256i t=_mm256_load_si256((const __m256i*)(p3+j));
               v = _mm256_add_epi8(v, s3>0?t:_mm256_sub_epi8(_mm256_setzero_si256(),t)); }
      _mm256_stream_si256((__m256i*)(d+j), v);
    }
  }
}


/* ===== lane c2k3: FUSED LEVEL-2 COMBINE.  Was 4 cmb() calls per k reading 12 x 256 KB for the
   7 leaves (1.75 MB) -- 8.75 MB of DRAM re-reads over the 7 k's.  One row-wise pass reads each
   leaf row exactly ONCE and writes all four quadrants.  Identical arithmetic to the 4 cmb calls:
   q00 = S0+S3-S4+S6, q01 = S2+S4, q10 = S1+S3, q11 = S0+S2-S1+S5. */
AVX2 static void cmb_s2f(int8_t*Cp,int m,const int8_t*S0,const int8_t*S1,const int8_t*S2,
                         const int8_t*S3,const int8_t*S4,const int8_t*S5,const int8_t*S6){
  const int h=m>>1;
  for (int i=0;i<h;i++){
    const int8_t *r0=S0+(size_t)i*h,*r1=S1+(size_t)i*h,*r2=S2+(size_t)i*h,*r3=S3+(size_t)i*h;
    const int8_t *r4=S4+(size_t)i*h,*r5=S5+(size_t)i*h,*r6=S6+(size_t)i*h;
    int8_t *d0=Cp+(size_t)i*m, *d1=d0+h, *d2=Cp+(size_t)(h+i)*m, *d3=d2+h;
    for (int j=0;j<h;j+=32){
      __m256i a0=_mm256_load_si256((const __m256i*)(r0+j));
      __m256i a1=_mm256_load_si256((const __m256i*)(r1+j));
      __m256i a2=_mm256_load_si256((const __m256i*)(r2+j));
      __m256i a3=_mm256_load_si256((const __m256i*)(r3+j));
      __m256i a4=_mm256_load_si256((const __m256i*)(r4+j));
      __m256i a5=_mm256_load_si256((const __m256i*)(r5+j));
      __m256i a6=_mm256_load_si256((const __m256i*)(r6+j));
      __m256i q0=_mm256_add_epi8(_mm256_sub_epi8(_mm256_add_epi8(a0,a3),a4),a6);
      __m256i q1=_mm256_add_epi8(a2,a4);
      __m256i q2=_mm256_add_epi8(a1,a3);
      __m256i q3=_mm256_add_epi8(_mm256_sub_epi8(_mm256_add_epi8(a0,a2),a1),a5);
      _mm256_stream_si256((__m256i*)(d0+j),q0);
      _mm256_stream_si256((__m256i*)(d1+j),q1);
      _mm256_stream_si256((__m256i*)(d2+j),q2);
      _mm256_stream_si256((__m256i*)(d3+j),q3);
    }
  }
}


/* ===== lane c2k3: FUSED LEVEL-1 COMBINE.  Same construction one level up: C's four quadrants
   written in ONE pass so each of the 7 MMS blocks is read EXACTLY ONCE (was 12 MB of reads for
   7 MB of data).  q00 = M0+M3-M4+M6, q01 = M2+M4, q10 = M1+M3, q11 = M0+M2-M1+M5. */
AVX2 static void cmb_l1f(int8_t*C,int n,int m){
  for (int i=0;i<m;i++){
    const int8_t *r0=MMS[0]+(size_t)i*m,*r1=MMS[1]+(size_t)i*m,*r2=MMS[2]+(size_t)i*m;
    const int8_t *r3=MMS[3]+(size_t)i*m,*r4=MMS[4]+(size_t)i*m,*r5=MMS[5]+(size_t)i*m;
    const int8_t *r6=MMS[6]+(size_t)i*m;
    int8_t *d0=C+(size_t)i*n, *d1=d0+m, *d2=C+(size_t)(m+i)*n, *d3=d2+m;
    for (int j=0;j<m;j+=32){
      __m256i a0=_mm256_load_si256((const __m256i*)(r0+j));
      __m256i a1=_mm256_load_si256((const __m256i*)(r1+j));
      __m256i a2=_mm256_load_si256((const __m256i*)(r2+j));
      __m256i a3=_mm256_load_si256((const __m256i*)(r3+j));
      __m256i a4=_mm256_load_si256((const __m256i*)(r4+j));
      __m256i a5=_mm256_load_si256((const __m256i*)(r5+j));
      __m256i a6=_mm256_load_si256((const __m256i*)(r6+j));
      __m256i q0=_mm256_add_epi8(_mm256_sub_epi8(_mm256_add_epi8(a0,a3),a4),a6);
      __m256i q1=_mm256_add_epi8(a2,a4);
      __m256i q2=_mm256_add_epi8(a1,a3);
      __m256i q3=_mm256_add_epi8(_mm256_sub_epi8(_mm256_add_epi8(a0,a2),a1),a5);
      _mm256_stream_si256((__m256i*)(d0+j),q0);
      _mm256_stream_si256((__m256i*)(d1+j),q1);
      _mm256_stream_si256((__m256i*)(d2+j),q2);
      _mm256_stream_si256((__m256i*)(d3+j),q3);
    }
  }
}

/* dst[i*h+j] = X[(r0+i)*n+(c0+j)] op Y[(r1+i)*n+(c1+j)],  op: 0 copy 1 add 2 sub (mod 256) */
AVX2 static void blk(int8_t*dst,const int8_t*X,int n,int r0,int c0,int h,
                     const int8_t*Y,int r1,int c1,int op){
  for (int i=0;i<h;i++){
    const int8_t *xa=X+(size_t)(r0+i)*n+c0, *ya=Y+(size_t)(r1+i)*n+c1;
    int8_t *d=dst+(size_t)i*h;
    int j=0;
    if (op==0)      for(;j+32<=h;j+=32) _mm256_store_si256((__m256i*)(d+j),
                          _mm256_load_si256((const __m256i*)(xa+j)));
    else if (op==1) for(;j+32<=h;j+=32) _mm256_store_si256((__m256i*)(d+j),
                          _mm256_add_epi8(_mm256_load_si256((const __m256i*)(xa+j)),
                                          _mm256_load_si256((const __m256i*)(ya+j))));
    else            for(;j+32<=h;j+=32) _mm256_store_si256((__m256i*)(d+j),
                          _mm256_sub_epi8(_mm256_load_si256((const __m256i*)(xa+j)),
                                          _mm256_load_si256((const __m256i*)(ya+j))));
    if (op) for(;j<h;j++) d[j]=(int8_t)(xa[j]+(op==1?ya[j]:-ya[j]));
  }
}

/* The GF(2) + combine tail of a sub-product, i.e. everything after the operand packers.  Split
   out so the FUSED path can reach it without materialising S2A/S2B first. */
AVX2BMI static void corr1024(void);
AVX2BMI static void corr512(void);
AVX2BMI static void corr256(void);

/* lane BW9: unrolled mirror of corr1024 for the m=512 leaf (W=8) */
AVX2BMI static void corr512(void){
  const int n=512, W=8;
  memset(Pbb,0,(size_t)n*W*8);
  const int KB=64;
  for (int kb=0; kb<n; kb+=KB){
    int w0=kb>>6;
    const char *bp0=(const char*)Bpb+(size_t)w0*4096;
    for (int i=0;i<n;i++){
      const uint64_t*row=A1b+(size_t)i*W+w0;
      uint64_t b0=row[0], b1=0;
      uint64_t *o=Pbb+(size_t)i*W;
      asm volatile(
        "vpxor %%xmm0,%%xmm0,%%xmm0\n\t"
        "vpxor %%xmm1,%%xmm1,%%xmm1\n\t"
        "testq %[b0], %[b0]\n\t"
        "jz 3%=f\n\t"
        "1%=:\n\t"
        "tzcntq %[b0], %%r11\n\t"
        "shlq $6, %%r11\n\t"
        "addq %[bp0], %%r11\n\t"
        "vpxor 0(%%r11), %%ymm0, %%ymm0\n\t"
        "vpxor 32(%%r11), %%ymm1, %%ymm1\n\t"
        "blsrq %[b0], %[b0]\n\t"
        "jnz 1%=b\n\t"
        "3%=:\n\t"
        "testq %[b1], %[b1]\n\t"
        "jz 4%=f\n\t"
        "2%=:\n\t"
        "tzcntq %[b1], %%r11\n\t"
        "shlq $6, %%r11\n\t"
        "addq %[bp0], %%r11\n\t"
        "vpxor 0(%%r11), %%ymm0, %%ymm0\n\t"
        "vpxor 32(%%r11), %%ymm1, %%ymm1\n\t"
        "blsrq %[b1], %[b1]\n\t"
        "jnz 2%=b\n\t"
        "4%=:\n\t"
        "vpxor   0(%[o]), %%ymm0, %%ymm0\n\t"
        "vmovdqu %%ymm0, 0(%[o])\n\t"
        "vpxor   32(%[o]), %%ymm1, %%ymm1\n\t"
        "vmovdqu %%ymm1, 32(%[o])\n\t"
        : [b0]"+r"(b0), [b1]"+r"(b1)
        : [bp0]"r"(bp0), [o]"r"(o)
        : "r11","cc","memory","ymm0","ymm1");
    }
  }
}

/* lane BW9: unrolled mirror of corr1024 for the m=256 leaf (W=4) */
AVX2BMI static void corr256(void){
  const int n=256, W=4;
  memset(Pbb,0,(size_t)n*W*8);
  const int KB=64;
  for (int kb=0; kb<n; kb+=KB){
    int w0=kb>>6;
    const char *bp0=(const char*)Bpb+(size_t)w0*2048;
    for (int i=0;i<n;i++){
      const uint64_t*row=A1b+(size_t)i*W+w0;
      uint64_t b0=row[0], b1=0;
      uint64_t *o=Pbb+(size_t)i*W;
      asm volatile(
        "vpxor %%xmm0,%%xmm0,%%xmm0\n\t"
        "testq %[b0], %[b0]\n\t"
        "jz 3%=f\n\t"
        "1%=:\n\t"
        "tzcntq %[b0], %%r11\n\t"
        "shlq $5, %%r11\n\t"
        "addq %[bp0], %%r11\n\t"
        "vpxor 0(%%r11), %%ymm0, %%ymm0\n\t"
        "blsrq %[b0], %[b0]\n\t"
        "jnz 1%=b\n\t"
        "3%=:\n\t"
        "testq %[b1], %[b1]\n\t"
        "jz 4%=f\n\t"
        "2%=:\n\t"
        "tzcntq %[b1], %%r11\n\t"
        "shlq $5, %%r11\n\t"
        "addq %[bp0], %%r11\n\t"
        "vpxor 0(%%r11), %%ymm0, %%ymm0\n\t"
        "blsrq %[b1], %[b1]\n\t"
        "jnz 2%=b\n\t"
        "4%=:\n\t"
        "vpxor   0(%[o]), %%ymm0, %%ymm0\n\t"
        "vmovdqu %%ymm0, 0(%[o])\n\t"
        : [b0]"+r"(b0), [b1]"+r"(b1)
        : [bp0]"r"(bp0), [o]"r"(o)
        : "r11","cc","memory","ymm0");
    }
  }
}
/* corr1024(): a hand-unrolled mirror of the SHIPPED corr16 for n=1024 (W=16, NY=4), which
   corr16's own `if (n==4096)` dispatch never reaches.  corr_pass3's inner `for(q<NY)` is
   runtime-bounded, so GCC cannot unroll it; corr16 exists because the unrolled form pays.
   Only the constants differ from corr16: 4 accumulators instead of 16, Bpb row stride 128 B
   instead of 512 B (shlq $7), and offsets 0/32/64/96 instead of 0..480. */
AVX2BMI static void corr1024(void){
  const int n=1024, W=16;
  memset(Pbb,0,(size_t)n*W*8);
  const int KB=64;
  for (int kb=0; kb<n; kb+=KB){
    int w0=kb>>6;
    const char *bp0=(const char*)Bpb+(size_t)w0*8192;
    for (int i=0;i<n;i++){
      const uint64_t*row=A1b+(size_t)i*W+w0;
      uint64_t b0=row[0], b1=0;
      uint64_t *o=Pbb+(size_t)i*W;
      asm volatile(
        "vpxor %%xmm0,%%xmm0,%%xmm0\n\t"
        "vpxor %%xmm1,%%xmm1,%%xmm1\n\t"
        "vpxor %%xmm2,%%xmm2,%%xmm2\n\t"
        "vpxor %%xmm3,%%xmm3,%%xmm3\n\t"
        "testq %[b0], %[b0]\n\t"
        "jz 3%=f\n\t"
        "1%=:\n\t"
        "tzcntq %[b0], %%r11\n\t"
        "shlq $7, %%r11\n\t"
        "addq %[bp0], %%r11\n\t"
        "vpxor 0(%%r11), %%ymm0, %%ymm0\n\t"
        "vpxor 32(%%r11), %%ymm1, %%ymm1\n\t"
        "vpxor 64(%%r11), %%ymm2, %%ymm2\n\t"
        "vpxor 96(%%r11), %%ymm3, %%ymm3\n\t"
        "blsrq %[b0], %[b0]\n\t"
        "jnz 1%=b\n\t"
        "3%=:\n\t"
        "testq %[b1], %[b1]\n\t"
        "jz 4%=f\n\t"
        "2%=:\n\t"
        "tzcntq %[b1], %%r11\n\t"
        "shlq $7, %%r11\n\t"
        "addq %[bp0], %%r11\n\t"
        "vpxor 0(%%r11), %%ymm0, %%ymm0\n\t"
        "vpxor 32(%%r11), %%ymm1, %%ymm1\n\t"
        "vpxor 64(%%r11), %%ymm2, %%ymm2\n\t"
        "vpxor 96(%%r11), %%ymm3, %%ymm3\n\t"
        "blsrq %[b1], %[b1]\n\t"
        "jnz 2%=b\n\t"
        "4%=:\n\t"
        "vpxor   0(%[o]), %%ymm0, %%ymm0\n\t"
        "vmovdqu %%ymm0, 0(%[o])\n\t"
        "vpxor   32(%[o]), %%ymm1, %%ymm1\n\t"
        "vmovdqu %%ymm1, 32(%[o])\n\t"
        "vpxor   64(%[o]), %%ymm2, %%ymm2\n\t"
        "vmovdqu %%ymm2, 64(%[o])\n\t"
        "vpxor   96(%[o]), %%ymm3, %%ymm3\n\t"
        "vmovdqu %%ymm3, 96(%[o])\n\t"
        : [b0]"+r"(b0), [b1]"+r"(b1)
        : [bp0]"r"(bp0), [o]"r"(o)
        : "r11","cc","memory","ymm0","ymm1","ymm2","ymm3");
    }
  }
}


/* ===================== lane CH3: NIBBLE-TABLE GF(2) PRODUCT =====================
   P[i][:] = XOR_{k: A1[i][k]=1} Bpb[k][:]   -- the same contract as corr512/corr1024,
   verified bit-identical against them on the real judge (work/lane_ch3_mmmc/rig/).
   Rationale and measurements: work/lane_ch3_mmmc/mk_nibcorr.py docstring.
   GROUPS = 16 groups (= one 64-bit A1 word) per k-block; table = 16*16*W words. */
static uint64_t TB[((size_t)NMAX/64)*256] __attribute__((aligned(64)));

#define DEF_NIBCORR(TAG, M)                                                    \
AVX2BMI static void nibcorr##TAG(void){                                        \
  const int n=M, W=n/64, G=n>>2, GB=16, NY=W>>2;                               \
  memset(Pbb,0,(size_t)n*W*8);                                                 \
  for (int g0=0; g0<G; g0+=GB){                                                \
    for (int t=0;t<GB;t++){                                                    \
      const int g=g0+t;                                                        \
      uint64_t *T=TB+(size_t)t*16*W;                                           \
      const uint64_t *r=Bpb+(size_t)(g*4)*W;                                   \
      for (int w=0;w<W;w++){                                                   \
        uint64_t a1=r[w], a2=r[W+w], a4=r[2*W+w], a8=r[3*W+w];                 \
        uint64_t x12=a1^a2, x14=a1^a4, x18=a1^a8;                              \
        T[ 0*W+w]=0;                                                           \
        T[ 1*W+w]=a1;  T[ 2*W+w]=a2;  T[ 4*W+w]=a4;  T[ 8*W+w]=a8;             \
        T[ 3*W+w]=x12; T[ 5*W+w]=x14; T[ 6*W+w]=a2^a4;  T[ 7*W+w]=x12^a4;      \
        T[ 9*W+w]=x18; T[10*W+w]=a2^a8; T[12*W+w]=a4^a8;                       \
        T[11*W+w]=a2^x18; T[13*W+w]=a4^x18; T[14*W+w]=a2^a4^a8;                \
        T[15*W+w]=x12^a4^a8;                                                   \
      }                                                                        \
    }                                                                          \
    for (int i=0;i<n;i++){                                                     \
      const uint64_t *arow=A1b+(size_t)i*W+(g0>>4);                            \
      __m256i acc[NY];                                                         \
      for (int q=0;q<NY;q++) acc[q]=_mm256_setzero_si256();                    \
      const uint64_t *T=TB;                                                    \
      for (int wb=0; wb<(GB>>4); wb++){                                        \
        const uint64_t word=arow[wb];                                          \
        _Pragma("GCC unroll 16")                                               \
        for (int b=0;b<16;b++, T+=(size_t)16*W){                               \
          const uint64_t *e=T+(size_t)(((word>>(4*b))&15u)*W);                 \
          for (int q=0;q<NY;q++)                                               \
            acc[q]=_mm256_xor_si256(acc[q],_mm256_load_si256((const __m256i*)(e+4*q))); \
        }                                                                      \
      }                                                                        \
      uint64_t *o=Pbb+(size_t)i*W;                                             \
      for (int q=0;q<NY;q++){                                                  \
        __m256i *po=(__m256i*)(o+4*q);                                         \
        _mm256_store_si256(po,_mm256_xor_si256(_mm256_load_si256((const __m256i*)po),acc[q])); \
      }                                                                        \
    }                                                                          \
  }                                                                            \
}
DEF_NIBCORR(512,512)
DEF_NIBCORR(1024,1024)

AVX2 static void submm_tail(int m,int8_t*Cp){
  GLDA = 2*(m) + PADA; GLDB = m + PADB;
  if (m==1024) corr1024(); else if (m==512) nibcorr512(); else if (m==256) corr256();
  else corr_pass3(m); expand_bits(m);
  const int GB=64, IB=128;
  for (int ib=0; ib<m; ib+=IB){
    const int ihi = (ib+IB<m)? ib+IB : m;
    for (int gb=0; gb<m; gb+=GB){
      const int ghi = (gb+GB<m)? gb+GB : m;
      for (int g=gb; g<ghi; g+=64){
        const int8_t *bi = BI3b+(size_t)(g>>6)*(m/2)*128;
        { int rev=0;
        for (int i=ib; i<ihi; i+=2){
          /* R1 boustrophedon: every other call walks A and BI BACKWARD, so it starts
             where the previous call stopped -- that data is still in L1. */
          const int8_t *ap=A0b+(size_t)i*GLDA;
          if (rev) mikro_u4r(m, ap+(2*m)-16, bi,
                             Cp+(size_t)i*m+g, PBb+(size_t)i*GLDB+g, 0, GLDA, GLDB);
          else     mikro_u4 (m, ap, bi,
                             Cp+(size_t)i*m+g, PBb+(size_t)i*GLDB+g, 0, GLDA, GLDB);
          rev^=1; }
        }
      }
    }
  }
}

/* one m x m sub-product through the SHIPPED pipeline, NT-stored to Cp (m = 2048 in the
   shipped dispatch; `m` is a parameter so the SAME code path gates at smaller m). */
AVX2 static void submm_plain(int m,const int8_t*Ap,const int8_t*Bp,int8_t*Cp){
  GLDA = 2*(m) + PADA; GLDB = m + PADB;
  build_A0A1(m,Ap); build_BI3Bp(m,Bp); submm_tail(m,Cp);
}

AVX2 static void submm(int m,const int8_t*Ap,const int8_t*Bp,int8_t*Cp);
#define S2MIN 1024
/* level 2: 7 sub-products of h=m/2, recombined by the SAME verified identity.
   ⛔ THE SUB-PRODUCT IS COMPUTED BY `submm_plain`, **NOT** BY `submm`.
   Calling `submm(h,...)` re-enters this function at h, and the inner call **overwrites the
   parent's own `S2A`/`S2B`/`S2M` scratch** -- so every `S2M[k]` except the last is destroyed
   before the combine reads it.  That is a 100 %-wrong build, and the 6-second A=I probe at
   n=4096 found it (87 % of bytes wrong, all four blocks).  If a deeper level is ever wanted,
   it needs its own scratch, not the shared pool. */
AVX2 static void submm_s2(int m,const int8_t*Ap,const int8_t*Bp,int8_t*Cp){
  GLDA = 2*((m>>1)) + PADA; GLDB = (m>>1) + PADB;
  const int h=m>>1, o=h;
  for (int k=0;k<7;k++){
    switch(k){
      case 0: buildA_q(h,m,Ap,0,0,Ap,o,o,1); buildB_q(h,m,Bp,0,0,Bp,o,o,1);  submm_tail(h,S2M[0]); break;
      case 1: buildA_q(h,m,Ap,o,0,Ap,o,o,1); buildB_q(h,m,Bp,0,0,Bp,0,0,0);  submm_tail(h,S2M[1]); break;
      case 2: buildA_q(h,m,Ap,0,0,Ap,0,0,0); buildB_q(h,m,Bp,0,o,Bp,o,o,2);  submm_tail(h,S2M[2]); break;
      case 3: buildA_q(h,m,Ap,o,o,Ap,o,o,0); buildB_q(h,m,Bp,o,0,Bp,0,0,2);  submm_tail(h,S2M[3]); break;
      case 4: buildA_q(h,m,Ap,0,0,Ap,0,o,1); buildB_q(h,m,Bp,o,o,Bp,o,o,0);  submm_tail(h,S2M[4]); break;
      case 5: buildA_q(h,m,Ap,o,0,Ap,0,0,2); buildB_q(h,m,Bp,0,0,Bp,0,o,1);  submm_tail(h,S2M[5]); break;
      case 6: buildA_q(h,m,Ap,0,o,Ap,o,o,2); buildB_q(h,m,Bp,o,0,Bp,o,o,1);  submm_tail(h,S2M[6]); break;
    }
  }
  _mm_sfence();
  cmb_s2f(Cp,m, S2M[0],S2M[1],S2M[2],S2M[3],S2M[4],S2M[5],S2M[6]);
  _mm_sfence();
}
AVX2 static void submm(int m,const int8_t*Ap,const int8_t*Bp,int8_t*Cp){
  if (m>=S2MIN) { submm_s2(m,Ap,Bp,Cp); return; }
  submm_plain(m,Ap,Bp,Cp);
}

AVX2 static void strassen1(int n,const int8_t*A,const int8_t*B,int8_t*C){
  const int m=n>>1, o=m;
  for (int k=0;k<7;k++){
    switch(k){
      case 0: blk(SA,A,n,0,0,m,A,o,o,1); blk(SB,B,n,0,0,m,B,o,o,1); break;
      case 1: blk(SA,A,n,o,0,m,A,o,o,1); blk(SB,B,n,0,0,m,B,0,0,0); break;
      case 2: blk(SA,A,n,0,0,m,A,0,0,0); blk(SB,B,n,0,o,m,B,o,o,2); break;
      case 3: blk(SA,A,n,o,o,m,A,o,o,0); blk(SB,B,n,o,0,m,B,0,0,2); break;
      case 4: blk(SA,A,n,0,0,m,A,0,o,1); blk(SB,B,n,o,o,m,B,o,o,0); break;
      case 5: blk(SA,A,n,o,0,m,A,0,0,2); blk(SB,B,n,0,0,m,B,0,o,1); break;
      case 6: blk(SA,A,n,0,o,m,A,o,o,2); blk(SB,B,n,o,0,m,B,o,o,1); break;
    }
    submm(m,SA,SB,MMS[k]);
  }
  _mm_sfence();
  cmb_l1f(C,n,m);
  _mm_sfence();
}
AVX2 void matrix_multiply(int n, const int8_t *A, const int8_t *B, int8_t *C){
  if (n<=0 || (n&255) || n>NMAX) { generic_mm(n,A,B,C); return; }
  if (n==2048) { strassen1(n,A,B,C); return; }
  /* x4: A1T is written by build_A1T and NEVER READ -- dead 16.78 MB + its transpose pass. */
  /* FUSED: one pass over A (was two), one over B (was two) */
  GLDA = 2*(n) + PADA; GLDB = n + PADB;
  build_A0A1(n,A); build_BI3Bp(n,B);
  if (n==4096) corr16(); else if (n==1024) corr1024();
  else corr_pass3(n); expand_bits(n);
  for (int g=0; g<n; g+=64)
    for (int i=0; i<n; i+=2)
      mikro_u4(n, A0b+(size_t)i*GLDA, BI3b+(size_t)(g>>6)*(n/2)*128,
               C+(size_t)i*n+g, PBb+(size_t)i*GLDB+g, 0, GLDA, GLDB);
  _mm_sfence();
}


CompilationN/AN/ACompile OKScore: N/A

Testcase #153.05 ms15 MB + 928 KBAcceptedScore: 100


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