Guest User

Untitled

a guest
Oct 23rd, 2026
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #version 300 es
  2. precision highp float;
  3. precision highp int;
  4. uniform sampler2D u_in, u_w, u_res;
  5. uniform int u_has_res;
  6. uniform int u_mode, u_in_len, u_out_len, u_row_offset, u_elem_base;
  7. uniform float u_f0, u_f1;
  8. uniform int u_i0, u_i1, u_i2, u_i3, u_i4, u_i5;
  9. out vec4 fragColor;
  10.  
  11. precise float dot4(precise vec4 a, precise vec4 b) {
  12.   precise float s = a.x*b.x;
  13.   s = s + a.y*b.y; s = s + a.z*b.z; s = s + a.w*b.w;
  14.   return s;
  15. }
  16. ivec2 widx(int i) { int t = i >> 2; return ivec2(t & 4095, t >> 12); }
  17. float getIn(int i) { return texelFetch(u_in, widx(i), 0)[i&3]; }
  18. float getW(int i) { return texelFetch(u_w, widx(i), 0)[i&3]; }
  19. float getRes(int i) { return texelFetch(u_res, widx(i), 0)[i&3]; }
  20.  
  21. void main() {
  22.   if (u_mode != 35 && gl_FragCoord.y >= 1.0) { fragColor = vec4(0); return; }
  23.   int px = int(gl_FragCoord.x);
  24.   float y[4] = float[4](0., 0., 0., 0.);
  25.  
  26.   // mode 3: SILU (unchanged)
  27.   if (u_mode == 3) {
  28.     for (int l = 0; l < 4; l++) {
  29.       int i = px*4 + l + u_elem_base;
  30.       if (i < u_in_len) { float x = getIn(i); y[l] = x / (1.0 + exp(-x)); }
  31.     }
  32.   }
  33.   // mode 7: RMSNORM — fast path via u_f1 (caller-precomputed r).
  34.   // Slow in-shader reduction retained as fallback when u_f1 == 0.
  35.   // WARNING: slow path is O(N) per pixel × N/4 pixels = O(N²) — catastrophic
  36.   // for large n_embd. Callers SHOULD pass r via u_f1 whenever possible.
  37.   else if (u_mode == 7) {
  38.     float r;
  39.     if (u_f1 > 0.0) {
  40.       r = u_f1;                                  // fast path: caller-computed
  41.     } else {
  42.       // slow fallback: in-shader reduction (O(N²) total)
  43.       float ss = 0.0;
  44.       for (int i = 0; i < 8192; i++) {
  45.         if (i >= u_in_len) break;
  46.         float v = getIn(i); ss += v*v;
  47.       }
  48.       r = inversesqrt(ss / float(u_in_len) + u_f0);
  49.     }
  50.     for (int l = 0; l < 4; l++) {
  51.       int i = px*4 + l + u_elem_base;
  52.       if (i < u_in_len) y[l] = getIn(i) * r * getW(i);
  53.     }
  54.   }
  55.   // mode 8: ROPE (runtime) — pow/cos/sin run per element.
  56.   // Prefer mode 9 when possible: mode 8 kept for compat / A-B benching.
  57.   else if (u_mode == 8) {
  58.     float base = (u_f1 > 0.0) ? u_f1 : 10000.0;
  59.     int hd = u_i0;
  60.     float pos = u_f0;
  61.     for (int l = 0; l < 4; l++) {
  62.       int i = px*4 + l + u_elem_base;
  63.       if (i >= u_in_len) continue;
  64.       int pair = (i % hd) & ~1;
  65.       int b = i - (i % hd) + pair;
  66.       float th = pos / pow(base, float(pair) / float(hd));
  67.       float c = cos(th), s = sin(th);
  68.       float x0 = getIn(b), x1 = getIn(b + 1);
  69.       if ((i & 1) == 0) y[l] = x0*c - x1*s;
  70.       else y[l] = x0*s + x1*c;
  71.     }
  72.   }
  73.   // mode 9: ROPE_PRECOMP — cos/sin pairs from u_w.
  74.   // Layout: w[2k] = cos(theta_k), w[2k+1] = sin(theta_k), k = 0..hd/2-1,
  75.   // where theta_k = pos / base^(2k/hd). Caller computes this in Python
  76.   // (or C) and passes the hd-length table as the weight buffer.
  77.   // Skips pow/cos/sin — only the four arithmetic ops per pair remain.
  78.   // Numerics match REFOps.rope bit-for-bit given the same f32 table.
  79.   else if (u_mode == 9) {
  80.     int hd = u_i0;
  81.     for (int l = 0; l < 4; l++) {
  82.       int i = px*4 + l + u_elem_base;
  83.       if (i >= u_in_len) continue;
  84.       int in_head = i % hd;
  85.       int pair_idx = in_head >> 1;
  86.       float c = getW(2*pair_idx);
  87.       float s = getW(2*pair_idx + 1);
  88.       int b = i - in_head + (in_head & ~1);
  89.       float x0 = getIn(b), x1 = getIn(b + 1);
  90.       if ((in_head & 1) == 0) y[l] = x0*c - x1*s;
  91.       else                    y[l] = x0*s + x1*c;
  92.     }
  93.   }
  94.   // mode 15: MUL
  95.   else if (u_mode == 15) {
  96.     for (int l = 0; l < 4; l++) {
  97.       int i = px*4 + l + u_elem_base;
  98.       if (i < u_in_len) y[l] = getIn(i) * getW(i);
  99.     }
  100.   }
  101.   // mode 16: ADD
  102.   else if (u_mode == 16) {
  103.     for (int l = 0; l < 4; l++) {
  104.       int i = px*4 + l + u_elem_base;
  105.       if (i < u_in_len) y[l] = getIn(i) + getW(i);
  106.     }
  107.   }
  108.   // mode 23: SWIGLU
  109.   else if (u_mode == 23) {
  110.     int mid = u_in_len / 2;
  111.     for (int l = 0; l < 4; l++) {
  112.       int i = px*4 + l;
  113.       if (i < u_out_len) {
  114.         float g = getIn(i);
  115.         float u = getIn(i + mid);
  116.         float sg = g / (1.0 + exp(-g));
  117.         y[l] = sg * u;
  118.       }
  119.     }
  120.   }
  121.   // mode 34: LINEAR f32 (4 rows per pixel, x4 hoisted out of jj loop)
  122.   else if (u_mode == 34) {
  123.     int base_row = (px + u_row_offset) * 4;
  124.     precise float acc[4];
  125.     acc[0] = (base_row+0 < u_out_len) ? getW(u_out_len*u_in_len + base_row+0) : 0.0;
  126.     acc[1] = (base_row+1 < u_out_len) ? getW(u_out_len*u_in_len + base_row+1) : 0.0;
  127.     acc[2] = (base_row+2 < u_out_len) ? getW(u_out_len*u_in_len + base_row+2) : 0.0;
  128.     acc[3] = (base_row+3 < u_out_len) ? getW(u_out_len*u_in_len + base_row+3) : 0.0;
  129.     for (int c = 0; c < 8192; c++) {
  130.       if ((c << 2) >= u_in_len) break;
  131.       precise vec4 x4 = precise vec4(getIn(c*4), getIn(c*4+1),
  132.                                       getIn(c*4+2), getIn(c*4+3));
  133.       for (int jj = 0; jj < 4; jj++) {
  134.         int row = base_row + jj;
  135.         if (row >= u_out_len) break;
  136.         int t = row * (u_in_len >> 2) + c;
  137.         precise vec4 w4 = texelFetch(u_w, ivec2(t & 4095, t >> 12), 0);
  138.         acc[jj] = acc[jj] + dot4(w4, x4);
  139.       }
  140.     }
  141.     for (int jj = 0; jj < 4; jj++) {
  142.       int row = base_row + jj;
  143.       if (row >= u_out_len) { y[jj] = -1e30; continue; }
  144.       if (u_has_res == 1) acc[jj] += getRes(row);
  145.       y[jj] = acc[jj];
  146.     }
  147.   }
  148.   // mode 35: SDPA_DENSE
  149.   else if (u_mode == 35) {
  150.     int Tq = u_i0, Tkv = u_i1, hd = u_i2;
  151.     int start_pos = u_i3, nh = u_i4, nkv = u_i5;
  152.     int d_model = nh * hd, kv_dim = nkv * hd;
  153.     int max_len = (u_f1 > 0.0) ? int(u_f1) : Tkv;
  154.     int vb = max_len * kv_dim;
  155.     int base_idx = (px + u_row_offset) * 4;
  156.     for (int jj = 0; jj < 4; jj++) {
  157.       int idx = base_idx + jj;
  158.       if (idx < Tq * d_model) {
  159.         int ti = idx / d_model; int r = idx - ti * d_model;
  160.         int hh = r / hd; int ki = r - hh * hd;
  161.         int hk = hh / (nh / nkv);
  162.         float sc = 1.0 / sqrt(float(hd));
  163.         int max_j = start_pos + ti + 1;
  164.         if (max_j > max_len) max_j = max_len;
  165.         precise float mx = -1e30, z = 0., acc = 0.;
  166.         for (int j = 0; j < 8192; j++) {
  167.           if (j >= max_j) break;
  168.           precise float s = 0.;
  169.           int qb = ti * d_model + hh * hd;
  170.           int kb = j * kv_dim + hk * hd;
  171.           int k = 0;
  172.           for (; k + 4 <= hd; k += 4) {
  173.             precise vec4 q4 = precise vec4(getIn(qb+k), getIn(qb+k+1),
  174.                                             getIn(qb+k+2), getIn(qb+k+3));
  175.             precise vec4 k4 = precise vec4(getW(kb+k), getW(kb+k+1),
  176.                                             getW(kb+k+2), getW(kb+k+3));
  177.             s = s + dot4(q4, k4);
  178.           }
  179.           for (; k < hd; k++) {
  180.             s = s + getIn(qb + k) * getW(kb + k);
  181.           }
  182.           s = s * sc;
  183.           precise float newmx = max(mx, s);
  184.           precise float rs = exp(mx - newmx);
  185.           precise float p = exp(s - newmx);
  186.           acc = acc * rs + p * getW(vb + j*kv_dim + hk*hd + ki);
  187.           z = z * rs + p;
  188.           mx = newmx;
  189.         }
  190.         y[jj] = acc / z;
  191.       }
  192.     }
  193.   }
  194.   fragColor = vec4(y[0], y[1], y[2], y[3]);
  195. }
Tags: glsl
Advertisement
Add Comment
Please, Sign In to add comment