| 3246 | const float av = fabsf(x[off + i]); |
| 3247 | if (av > amax) amax = av; |
| 3248 | } |
| 3249 | |
| 3250 | if (amax < 1.0e-4f) amax = 1.0e-4f; |
| 3251 | const float scale = ldexpf(1.0f, (int)ceilf(log2f(amax / 448.0f))); |
| 3252 | for (uint32_t i = 0; i < 64; i++) { |
| 3253 | float v = x[off + i] / scale; |
| 3254 | if (v > 448.0f) v = 448.0f; |
| 3255 | if (v < -448.0f) v = -448.0f; |
| 3256 | x[off + i] = dsv4_e4m3fn_dequant_cpu(v) * scale; |
| 3257 | } |
| 3258 | } |
| 3259 | } |
| 3260 | |
| 3261 | static float dsv4_e2m1fn_value_cpu(int i) { |
| 3262 | static const float values[8] = { |
| 3263 | 0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 3.0f, 4.0f, 6.0f, |
| 3264 | }; |
| 3265 | return values[i & 7]; |
| 3266 | } |
| 3267 | |
| 3268 | static float dsv4_e2m1fn_dequant_cpu(float x) { |
| 3269 | const float sign = x < 0.0f ? -1.0f : 1.0f; |
| 3270 | const float ax = fminf(fabsf(x), 6.0f); |
| 3271 | int best = 0; |
| 3272 | float best_diff = fabsf(ax - dsv4_e2m1fn_value_cpu(0)); |
| 3273 | for (int i = 1; i < 8; i++) { |
| 3274 | const float diff = fabsf(ax - dsv4_e2m1fn_value_cpu(i)); |
| 3275 | if (diff < best_diff || (diff == best_diff && (i & 1) == 0 && (best & 1) != 0)) { |
| 3276 | best = i; |
| 3277 | best_diff = diff; |
| 3278 | } |
| 3279 | } |
| 3280 | return sign * dsv4_e2m1fn_value_cpu(best); |
| 3281 | } |
| 3282 | |
| 3283 | static void dsv4_hadamard128_inplace_cpu(float *x) { |
| 3284 | for (uint32_t stride = 1; stride < 128; stride <<= 1) { |
| 3285 | for (uint32_t base = 0; base < 128; base += 2u * stride) { |
| 3286 | for (uint32_t i = 0; i < stride; i++) { |
| 3287 | const float a = x[base + i]; |
| 3288 | const float b = x[base + stride + i]; |
| 3289 | x[base + i] = a + b; |
| 3290 | x[base + stride + i] = a - b; |
| 3291 | } |
| 3292 | } |
no test coverage detected