| 2179 | // ====================== 6-bit (de)-quantization |
| 2180 | |
| 2181 | void quantize_row_q6_K_reference(const float * restrict x, block_q6_K * restrict y, int k) { |
| 2182 | assert(k % QK_K == 0); |
| 2183 | const int nb = k / QK_K; |
| 2184 | |
| 2185 | int8_t L[QK_K]; |
| 2186 | float scales[QK_K/16]; |
| 2187 | |
| 2188 | for (int i = 0; i < nb; i++) { |
| 2189 | |
| 2190 | float max_scale = 0; |
| 2191 | float max_abs_scale = 0; |
| 2192 | |
| 2193 | for (int ib = 0; ib < QK_K/16; ++ib) { |
| 2194 | |
| 2195 | const float scale = make_qx_quants(16, 32, x + 16*ib, L + 16*ib, 1); |
| 2196 | scales[ib] = scale; |
| 2197 | |
| 2198 | const float abs_scale = fabsf(scale); |
| 2199 | if (abs_scale > max_abs_scale) { |
| 2200 | max_abs_scale = abs_scale; |
| 2201 | max_scale = scale; |
| 2202 | } |
| 2203 | |
| 2204 | } |
| 2205 | |
| 2206 | if (!max_abs_scale) { |
| 2207 | memset(&y[i], 0, sizeof(block_q6_K)); |
| 2208 | y[i].d = GGML_FP32_TO_FP16(0.f); |
| 2209 | x += QK_K; |
| 2210 | continue; |
| 2211 | } |
| 2212 | |
| 2213 | float iscale = -128.f/max_scale; |
| 2214 | y[i].d = GGML_FP32_TO_FP16(1/iscale); |
| 2215 | for (int ib = 0; ib < QK_K/16; ++ib) { |
| 2216 | y[i].scales[ib] = MIN(127, nearest_int(iscale*scales[ib])); |
| 2217 | } |
| 2218 | |
| 2219 | for (int j = 0; j < QK_K/16; ++j) { |
| 2220 | float d = GGML_FP16_TO_FP32(y[i].d) * y[i].scales[j]; |
| 2221 | if (!d) { |
| 2222 | continue; |
| 2223 | } |
| 2224 | for (int ii = 0; ii < 16; ++ii) { |
| 2225 | int l = nearest_int(x[16*j + ii]/d); |
| 2226 | l = MAX(-32, MIN(31, l)); |
| 2227 | L[16*j + ii] = l + 32; |
| 2228 | } |
| 2229 | } |
| 2230 | |
| 2231 | uint8_t * restrict ql = y[i].ql; |
| 2232 | uint8_t * restrict qh = y[i].qh; |
| 2233 | #if QK_K == 256 |
| 2234 | for (int j = 0; j < QK_K; j += 128) { |
| 2235 | for (int l = 0; l < 32; ++l) { |
| 2236 | const uint8_t q1 = L[j + l + 0] & 0xF; |
| 2237 | const uint8_t q2 = L[j + l + 32] & 0xF; |
| 2238 | const uint8_t q3 = L[j + l + 64] & 0xF; |
no test coverage detected