| 864 | |
| 865 | template <typename T, int DATA_TYPE> |
| 866 | void gemv_4bit_inference( |
| 867 | int64_t M, int64_t N, int64_t K, const T* __restrict__ x, const unsigned char* __restrict__ w, |
| 868 | const T* __restrict__ absmax, T* __restrict__ out, int64_t blocksize, int64_t x_stride, int64_t out_stride |
| 869 | ) { |
| 870 | constexpr int64_t BLOCK_M = block_size_m(); // 32 |
| 871 | constexpr int64_t BLOCK_N = block_size_n(); // 32 |
| 872 | const int64_t MB = div_up(M, BLOCK_M); // (x + y -1)/ y, res = 1 when M <= 32 |
| 873 | const int64_t NB = div_up(N, BLOCK_N); |
| 874 | // TODO: enable brgemm in the future. |
| 875 | // const bool use_brgemm = M > 4; |
| 876 | // const bool use_brgemm_dequant_out = M > 512; |
| 877 | // T* Btmp_start = nullptr; |
| 878 | // l2 cache block for n |
| 879 | int64_t cache_blocks_nb = get_cache_blocks<T>(BLOCK_N * K); |
| 880 | parallel_2d(MB, NB, [&](int64_t begin_mb, int64_t end_mb, int64_t begin_nb, int64_t end_nb) { |
| 881 | // for brgemm, use float32 for accumulate |
| 882 | alignas(64) float Ctmp[BLOCK_M * BLOCK_N]; |
| 883 | alignas(64) T Btmp_inner[BLOCK_N * BLOCK_K]; // BLOCK_K = 128 |
| 884 | for (int64_t nbb = begin_nb; nbb < end_nb; nbb += cache_blocks_nb) { |
| 885 | for (int64_t mb = begin_mb; mb < end_mb; ++mb) { // 0-1 |
| 886 | for (int64_t nb = nbb; nb < std::min(nbb + cache_blocks_nb, end_nb); ++nb) { |
| 887 | int64_t mb_start = mb * BLOCK_M; // 0 |
| 888 | int64_t mb_size = std::min(M - mb_start, BLOCK_M); |
| 889 | int64_t nb_start = nb * BLOCK_N; |
| 890 | int64_t nb_size = std::min(N - nb_start, BLOCK_N); |
| 891 | tinygemm_kernel<T, DATA_TYPE>( |
| 892 | /* A */ x + mb_start * x_stride, |
| 893 | /* B */ w + nb_start * K / 2, // divide by 2 since w is u4 packed in u8, K is w.size(1) * 2 |
| 894 | /* C */ out + mb_start * out_stride + nb_start, |
| 895 | /* Bs */ absmax + nb_start, |
| 896 | /* Btmp */ Btmp_inner, |
| 897 | /* Ctmp */ Ctmp, |
| 898 | /* M */ mb_size, |
| 899 | /* N */ nb_size, |
| 900 | /* K */ K, |
| 901 | /* gs */ blocksize, // group_size |
| 902 | /* lda */ x_stride, |
| 903 | /* ldb */ nb_size, |
| 904 | /* ldc */ out_stride, |
| 905 | /* sBz */ N, |
| 906 | /* sBs */ N |
| 907 | ); |
| 908 | } |
| 909 | } |
| 910 | } |
| 911 | // if (use_brgemm) { |
| 912 | // at::native::cpublas::brgemm_release(); |
| 913 | // } |
| 914 | }); |
| 915 | } |
| 916 | #endif |
| 917 | |
| 918 | //============================================================== |
nothing calls this directly
no test coverage detected