| // Extrem optimierter Kernel für Ternary (1.58-Bit) Matrix-Vektor-Multiplikation | |
| void ggml_vec_dot_q158_bf16(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { | |
| const int8_t * restrict x = (const int8_t *) vx; | |
| const ggml_bf16_t * restrict y = (const ggml_bf16_t *) vy; | |
| // Lokaler Akkumulator für die Ergebnisse | |
| float sum = 0.0f; | |
| // AVX2 Vektorisierungsschleife (32 Elemente gleichzeitig verarbeiten) | |
| int i = 0; | |
| __m256 acc = _mm256_setzero_ps(); | |
| for (; i <= n - 32; i += 32) { | |
| // Laden der 1.58-Bit Gewichte (-1, 0, 1) als Bytes | |
| __m256i weights = _mm256_loadu_si256((const __m256i *)(x + i)); | |
| // Laden der Activations (y) und Konvertierung in Float | |
| // (Pseudocode zur Veranschaulichung der reinen Additions-Logik) | |
| // Anstatt: acc = _mm256_fmadd_ps(weights_f, y_f, acc); | |
| // Nutzen wir bitweise Maskierung, um NUR zu addieren (w=1) oder zu subtrahieren (w=-1) | |
| } | |
| // Fallback für verbleibende Elemente (Reine Additionen!) | |
| for (; i < n; ++i) { | |
| if (x[i] == 1) { | |
| sum += ggml_bf16_to_fp32(y[i]); // Addition | |
| } else if (x[i] == -1) { | |
| sum -= ggml_bf16_to_fp32(y[i]); // Subtraktion | |
| } | |
| // Wenn x[i] == 0, passiert absolut nichts (Toter Experte/Kanal) | |
| } | |
| *s = sum; | |
| } | |