This method runs some precomputations on linear weights when possible.
| 387 | |
| 388 | // This method runs some precomputations on linear weights when possible. |
| 389 | void Model::process_linear_weights() { |
| 390 | if (_device != Device::CPU) |
| 391 | return; // There is currently no processing for non CPU device. |
| 392 | |
| 393 | const bool pack_weights = cpu::pack_gemm_weights(_effective_compute_type); |
| 394 | const bool transpose = true; |
| 395 | const float alpha = 1; |
| 396 | |
| 397 | const auto variable_index = _variable_index; |
| 398 | for (const auto& pair : variable_index) { |
| 399 | const std::string& name = pair.first; |
| 400 | if (!is_linear_weight(name)) |
| 401 | continue; |
| 402 | |
| 403 | const StorageView& weight = *pair.second; |
| 404 | const DataType dtype = weight.dtype(); |
| 405 | const dim_t k = weight.dim(1); |
| 406 | const dim_t n = weight.dim(0); |
| 407 | |
| 408 | // If the target Gemm implementation prefers the u8s8s32 format, we can shift |
| 409 | // the input of linear layers to the u8 domain and add a compensation term. |
| 410 | // This term only depends on the linear weight, so we can compute it once and |
| 411 | // store it as a model variable. |
| 412 | if (dtype == DataType::INT8 && cpu::prefer_u8s8s32_gemm()) { |
| 413 | StorageView compensation = ops::Gemm::compensate_u8_input(weight, transpose, k, n, alpha); |
| 414 | register_variable(name + "_compensation", std::move(compensation)); |
| 415 | } |
| 416 | |
| 417 | // If requested, linear weights can be packed for the Gemm call. |
| 418 | // Only 2D weights are supported; Conv weights are 3D and use a different code path. |
| 419 | if (pack_weights && is_packable(name) && weight.rank() == 2) { |
| 420 | StorageView packed_weight = ops::Gemm::pack_b_input(weight, transpose, k, n, alpha); |
| 421 | register_variable(name + "_packed", std::move(packed_weight)); |
| 422 | remove_variable(name); // The original weight is no longer needed. |
| 423 | } |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | static DataType get_dtype_from_item_size(uint8_t item_size) { |
| 428 | // This is the old (and flawed) logic of resolving the dtype of saved variables. |
no test coverage detected