| 145 | } |
| 146 | |
| 147 | void quantize_row_q2_K_ref(const float * __restrict__ x, block_q2_K * __restrict__ y, int64_t k) { |
| 148 | assert(k % QK_K == 0); |
| 149 | const int nb = k / QK_K; |
| 150 | |
| 151 | uint8_t L[QK_K]; |
| 152 | uint8_t Laux[16]; |
| 153 | float weights[16]; |
| 154 | float mins[QK_K/16]; |
| 155 | float scales[QK_K/16]; |
| 156 | |
| 157 | const float q4scale = 15.f; |
| 158 | |
| 159 | for (int i = 0; i < nb; i++) { |
| 160 | float max_scale = 0; // as we are deducting the min, scales are always positive |
| 161 | float max_min = 0; |
| 162 | for (int j = 0; j < QK_K/16; ++j) { |
| 163 | for (int l = 0; l < 16; ++l) weights[l] = fabsf(x[16*j + l]); |
| 164 | scales[j] = make_qkx2_quants(16, 3, x + 16*j, weights, L + 16*j, &mins[j], Laux, -0.5f, 0.1f, 15, true); |
| 165 | float scale = scales[j]; |
| 166 | if (scale > max_scale) { |
| 167 | max_scale = scale; |
| 168 | } |
| 169 | float min = mins[j]; |
| 170 | if (min > max_min) { |
| 171 | max_min = min; |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | if (max_scale > 0) { |
| 176 | float iscale = q4scale/max_scale; |
| 177 | for (int j = 0; j < QK_K/16; ++j) { |
| 178 | int l = nearest_int(iscale*scales[j]); |
| 179 | y[i].scales[j] = l; |
| 180 | } |
| 181 | y[i].d = float_to_half(max_scale/q4scale); |
| 182 | } else { |
| 183 | for (int j = 0; j < QK_K/16; ++j) y[i].scales[j] = 0; |
| 184 | y[i].d = float_to_half(0.f); |
| 185 | } |
| 186 | if (max_min > 0) { |
| 187 | float iscale = q4scale/max_min; |
| 188 | for (int j = 0; j < QK_K/16; ++j) { |
| 189 | int l = nearest_int(iscale*mins[j]); |
| 190 | y[i].scales[j] |= (l << 4); |
| 191 | } |
| 192 | y[i].dmin = float_to_half(max_min/q4scale); |
| 193 | } else { |
| 194 | y[i].dmin = float_to_half(0.f); |
| 195 | } |
| 196 | for (int j = 0; j < QK_K/16; ++j) { |
| 197 | const float d = half_to_float(y[i].d) * (y[i].scales[j] & 0xF); |
| 198 | if (!d) continue; |
| 199 | const float dm = half_to_float(y[i].dmin) * (y[i].scales[j] >> 4); |
| 200 | for (int ii = 0; ii < 16; ++ii) { |
| 201 | int l = nearest_int((x[16*j + ii] + dm)/d); |
| 202 | l = std::max(0, std::min(3, l)); |
| 203 | L[16*j + ii] = l; |
| 204 | } |
no test coverage detected