| #include <stdint.h> |
| #include <stddef.h> |
| #include <immintrin.h> |
|
|
| #ifdef _OPENMP |
| #include <omp.h> |
| #endif |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void prime_linear_forward( |
| const float* restrict x, |
| const uint16_t* restrict weight_indices, |
| const float* restrict lut, |
| float* restrict y, |
| int batch_size, |
| int in_features, |
| int out_features |
| ) { |
| #pragma omp parallel for collapse(2) |
| for (int b = 0; b < batch_size; ++b) { |
| for (int o = 0; o < out_features; ++o) { |
| |
| const uint16_t* w_row = &weight_indices[o * in_features]; |
| const float* x_row = &x[b * in_features]; |
| |
| int i = 0; |
| float sum = 0.0f; |
| |
| #if defined(__AVX512F__) && defined(__AVX512BW__) |
| __m512 sum_vec = _mm512_setzero_ps(); |
| |
| |
| for (; i <= in_features - 16; i += 16) { |
| |
| __m256i w_16bit = _mm256_loadu_si256((const __m256i*)&w_row[i]); |
| |
| |
| __m512i w_32bit = _mm512_cvtepu16_epi32(w_16bit); |
| |
| |
| __m512 lut_vals = _mm512_i32gather_ps(w_32bit, lut, 4); |
| |
| |
| __m512 x_vals = _mm512_loadu_ps(&x_row[i]); |
| |
| |
| sum_vec = _mm512_fmadd_ps(lut_vals, x_vals, sum_vec); |
| } |
| |
| |
| sum += _mm512_reduce_add_ps(sum_vec); |
| #endif |
| |
| |
| for (; i < in_features; ++i) { |
| uint16_t idx = w_row[i]; |
| float w_val = lut[idx]; |
| sum += x_row[i] * w_val; |
| } |
| |
| y[b * out_features + o] = sum; |
| } |
| } |
| } |
|
|