MCPcopy Create free account
hub / github.com/ml-explore/mlx / quantize

Function quantize

mlx/backend/cpu/quantized.cpp:1149–1211  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1147
1148template <typename T, typename U>
1149void quantize(
1150 const T* w,
1151 U* out,
1152 T* scales,
1153 T* biases,
1154 int bits,
1155 int group_size,
1156 size_t w_size) {
1157 float n_bins = (1 << bits) - 1;
1158 float eps = 1e-7;
1159
1160 bool power_of_2_bits = is_power_of_2(bits);
1161 int el_per_int = get_pack_factor(bits, 32);
1162 int bytes_per_pack = get_bytes_per_pack(bits);
1163 int int_per_group = group_size * bytes_per_pack / el_per_int;
1164 size_t n_groups = w_size / group_size;
1165
1166 for (size_t i = 0; i < n_groups; ++i) {
1167 size_t w_idx = i * group_size;
1168 float w_min = std::numeric_limits<float>::infinity();
1169 float w_max = -w_min;
1170 for (int j = 0; j < group_size; ++j) {
1171 w_max = std::max(w_max, (float)w[w_idx + j]);
1172 w_min = std::min(w_min, (float)w[w_idx + j]);
1173 }
1174 bool mask = std::abs(w_min) > std::abs(w_max);
1175 float scale = std::max((w_max - w_min) / n_bins, eps);
1176 scale = mask ? scale : -scale;
1177
1178 float edge = mask ? w_min : w_max;
1179 float q0 = std::rint(edge / scale);
1180 float bias = 0;
1181 if (q0 != 0) {
1182 scale = edge / q0;
1183 bias = edge;
1184 }
1185 size_t out_idx = i * int_per_group;
1186 for (int j = 0; j < int_per_group / bytes_per_pack; ++j) {
1187 uint64_t out_el = 0;
1188 for (int k = 0; k < el_per_int; ++k) {
1189 float w_el = w[w_idx + j * el_per_int + k];
1190 w_el = std::rint((w_el - bias) / scale);
1191 w_el = std::min(std::max(w_el, 0.0f), n_bins);
1192 out_el |= static_cast<uint64_t>(w_el) << (k * bits);
1193 }
1194 if (power_of_2_bits) {
1195 out[out_idx + j] = out_el;
1196 } else if (bits == 5) {
1197 out[out_idx + bytes_per_pack * j] = out_el & 0xff;
1198 out[out_idx + bytes_per_pack * j + 1] = (out_el & 0xff00) >> 8;
1199 out[out_idx + bytes_per_pack * j + 2] = (out_el & 0xff0000) >> 16;
1200 out[out_idx + bytes_per_pack * j + 3] = (out_el & 0xff000000) >> 24;
1201 out[out_idx + bytes_per_pack * j + 4] = (out_el & 0xff00000000) >> 32;
1202 } else {
1203 out[out_idx + bytes_per_pack * j] = out_el & 0xff;
1204 out[out_idx + bytes_per_pack * j + 1] = (out_el & 0xff00) >> 8;
1205 out[out_idx + bytes_per_pack * j + 2] = (out_el & 0xff0000) >> 16;
1206 }

Callers

nothing calls this directly

Calls 7

is_power_of_2Function · 0.85
absFunction · 0.85
rintFunction · 0.85
get_pack_factorFunction · 0.50
get_bytes_per_packFunction · 0.50
maxFunction · 0.50
minFunction · 0.50

Tested by

no test coverage detected