1212
1313using namespace BinSearch ;
1414
15-
1615#if defined(__AVX512F__)
1716#include < immintrin.h>
1817
1918inline __m256i cvt_fp32_to_fp16 (const __m512 src) {
2019 return _mm512_cvtps_ph (src, (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
21- }
20+ }
2221
2322inline __m256i cvt_fp32_to_bf16 (const __m512 src) {
24- #if defined(__AVX512BF16__)
25- return reinterpret_cast <__m256i>(_mm512_cvtneps_pbh (src));
26- #else
27- __m512i value = _mm512_castps_si512 (src);
28- __m512i nan = _mm512_set1_epi32 (0xffff );
29- auto mask_value = _mm512_cmp_ps_mask (src, src, _CMP_ORD_Q);
30- __m512i ones = _mm512_set1_epi32 (0x1 );
31- __m512i vec_bias = _mm512_set1_epi32 (0x7fff );
32- // uint32_t lsb = (input >> 16) & 1;
33- auto t_value = _mm512_and_si512 (_mm512_srli_epi32 (value, 16 ), ones);
34- // uint32_t rounding_bias = 0x7fff + lsb;
35- t_value = _mm512_add_epi32 (t_value, vec_bias);
36- // input += rounding_bias;
37- t_value = _mm512_add_epi32 (t_value, value);
38- // input = input >> 16;
39- t_value = _mm512_srli_epi32 (t_value, 16 );
40- // Check NaN before converting back to bf16
41- t_value = _mm512_mask_blend_epi32 (mask_value, nan, t_value);
42- return _mm512_cvtusepi32_epi16 (t_value);
43- #endif
23+ #if defined(__AVX512BF16__)
24+ return reinterpret_cast <__m256i>(_mm512_cvtneps_pbh (src));
25+ #else
26+ __m512i value = _mm512_castps_si512 (src);
27+ __m512i nan = _mm512_set1_epi32 (0xffff );
28+ auto mask_value = _mm512_cmp_ps_mask (src, src, _CMP_ORD_Q);
29+ __m512i ones = _mm512_set1_epi32 (0x1 );
30+ __m512i vec_bias = _mm512_set1_epi32 (0x7fff );
31+ // uint32_t lsb = (input >> 16) & 1;
32+ auto t_value = _mm512_and_si512 (_mm512_srli_epi32 (value, 16 ), ones);
33+ // uint32_t rounding_bias = 0x7fff + lsb;
34+ t_value = _mm512_add_epi32 (t_value, vec_bias);
35+ // input += rounding_bias;
36+ t_value = _mm512_add_epi32 (t_value, value);
37+ // input = input >> 16;
38+ t_value = _mm512_srli_epi32 (t_value, 16 );
39+ // Check NaN before converting back to bf16
40+ t_value = _mm512_mask_blend_epi32 (mask_value, nan, t_value);
41+ return _mm512_cvtusepi32_epi16 (t_value);
42+ #endif
4443}
4544
4645static inline __m512 set_nf4_lut () {
4746 return _mm512_set_ps (
48- 1 .0f ,
49- 0.7229568362236023 ,
50- 0.5626170039176941 ,
51- 0.44070982933044434 ,
52- 0.33791524171829224 ,
53- 0.24611230194568634 ,
54- 0.16093020141124725 ,
55- 0.07958029955625534 ,
56- 0 .0f ,
57- -0.09105003625154495 ,
58- -0.18477343022823334 ,
59- -0.28444138169288635 ,
60- -0.39491748809814453 ,
61- -0.5250730514526367 ,
62- -0.6961928009986877 ,
63- -1 .0f );
47+ 1 .0f , 0.7229568362236023 , 0.5626170039176941 , 0.44070982933044434 , 0.33791524171829224 , 0.24611230194568634 ,
48+ 0.16093020141124725 , 0.07958029955625534 , 0 .0f , -0.09105003625154495 , -0.18477343022823334 ,
49+ -0.28444138169288635 , -0.39491748809814453 , -0.5250730514526367 , -0.6961928009986877 , -1 .0f
50+ );
6451}
52+
6553static inline __m512 set_fp4_lut () {
6654 return _mm512_set_ps (
67- -0 .2500f ,
68- -0 .16666667f ,
69- -0 .5000f ,
70- -0 .33333333f ,
71- -1 .0000f ,
72- -0 .66666667f ,
73- -5 .208333333e-03f ,
74- 0 .0000f ,
75- 0 .2500f ,
76- 0 .16666667f ,
77- 0 .5000f ,
78- 0 .33333333f ,
79- 1 .0000f ,
80- 0 .66666667f ,
81- 5 .208333333e-03f ,
82- 0 .0000f );
55+ -0 .2500f , -0 .16666667f , -0 .5000f , -0 .33333333f , -1 .0000f , -0 .66666667f , -5 .208333333e-03f , 0 .0000f , 0 .2500f ,
56+ 0 .16666667f , 0 .5000f , 0 .33333333f , 1 .0000f , 0 .66666667f , 5 .208333333e-03f , 0 .0000f
57+ );
8358}
8459#endif
8560
8661// 4-bit (FP4 / NF4) dequantization helper extracted from the original else branch.
87- // DATA_TYPE: 1 = FP4, 0 = NF4
62+ // DATA_TYPE: 1 = FP4, 2 = NF4
8863template <typename T, int DATA_TYPE >
89- void dequantizeBlockwise4bitCpu (unsigned char * A,
90- const float * absmax,
91- T* out,
92- long long blocksize,
93- long long m,
94- long long n) {
95- static_assert (DATA_TYPE == 0 || DATA_TYPE == 1 ,
96- " dequantizeBlockwise4bitCpu called with non 4-bit DATA_TYPE" );
97- if (blocksize <= 0 || m < 0 || n <= 0 ) return ;
64+ void dequantizeBlockwise4bitCpu (
65+ unsigned char * A, const float * absmax, T* out, long long blocksize, long long m, long long n
66+ ) {
67+ static_assert (DATA_TYPE == 1 || DATA_TYPE == 2 , " dequantizeBlockwise4bitCpu called with non 4-bit DATA_TYPE" );
68+ if (blocksize <= 0 || m < 0 || n <= 0 )
69+ return ;
9870
9971#if defined(__AVX512F__)
10072 long long dim_0 = m;
@@ -119,10 +91,10 @@ void dequantizeBlockwise4bitCpu(unsigned char* A,
11991 uint64_t high = 0 ;
12092 uint64_t low = 0 ;
12193 for (int i = 0 ; i < 4 ; ++i) {
122- low |= ((packed >> (2 * i * 4 )) & 0xf ) << ((2 *i+ 1 ) * 8 );
123- low |= ((packed >> ((2 *i+ 1 ) * 4 )) & 0xf ) << (2 * i * 8 );
124- high |= ((packed >> (2 * i * 4 + 32 )) & 0xf ) << ((2 *i+ 1 ) * 8 );
125- high |= ((packed >> ((2 *i+ 1 ) * 4 + 32 )) & 0xf ) << (2 * i * 8 );
94+ low |= ((packed >> (2 * i * 4 )) & 0xf ) << ((2 * i + 1 ) * 8 );
95+ low |= ((packed >> ((2 * i + 1 ) * 4 )) & 0xf ) << (2 * i * 8 );
96+ high |= ((packed >> (2 * i * 4 + 32 )) & 0xf ) << ((2 * i + 1 ) * 8 );
97+ high |= ((packed >> ((2 * i + 1 ) * 4 + 32 )) & 0xf ) << (2 * i * 8 );
12698 }
12799 __m128i packed_128 = _mm_set_epi64x (high, low);
128100 __m512i vint32 = _mm512_cvtepu8_epi32 (packed_128);
@@ -133,13 +105,11 @@ void dequantizeBlockwise4bitCpu(unsigned char* A,
133105 // Store results
134106 T* pout = &out[block_idx * dim_1 + k * 2 ];
135107 if constexpr (std::is_same<T, float >()) {
136- _mm512_storeu_ps (pout, vout);
108+ _mm512_storeu_ps (pout, vout);
137109 } else if constexpr (std::is_same<T, bf16_t >()) {
138- _mm256_storeu_si256 (
139- (__m256i*)pout, cvt_fp32_to_bf16 (vout));
110+ _mm256_storeu_si256 ((__m256i*)pout, cvt_fp32_to_bf16 (vout));
140111 } else if constexpr (std::is_same<T, fp16_t >()) {
141- _mm256_storeu_si256 (
142- (__m256i*)pout, cvt_fp32_to_fp16 (vout));
112+ _mm256_storeu_si256 ((__m256i*)pout, cvt_fp32_to_fp16 (vout));
143113 }
144114 }
145115 }
@@ -157,11 +127,9 @@ void dequantizeBlockwise4bitCpu(unsigned char* A,
157127 unsigned char byte = A[byte_index];
158128
159129 // High nibble first (matches previous code logic)
160- float v0 = (DATA_TYPE == 1 ? dDequantizeFP4 (byte >> 4 )
161- : dDequantizeNF4 (byte >> 4 )) * scale;
130+ float v0 = (DATA_TYPE == 1 ? dDequantizeFP4 (byte >> 4 ) : dDequantizeNF4 (byte >> 4 )) * scale;
162131 // Low nibble second
163- float v1 = (DATA_TYPE == 1 ? dDequantizeFP4 (byte & 0x0F )
164- : dDequantizeNF4 (byte & 0x0F )) * scale;
132+ float v1 = (DATA_TYPE == 1 ? dDequantizeFP4 (byte & 0x0F ) : dDequantizeNF4 (byte & 0x0F )) * scale;
165133
166134 if constexpr (std::is_same<T, bf16_t >::value) {
167135 out[block_idx + i] = float_to_bf16 (v0);
@@ -184,20 +152,17 @@ void dequantizeBlockwise4bitCpu(unsigned char* A,
184152 }
185153}
186154
187-
188155template <typename T>
189- void dequantizeBlockwise8bitCpu (float * code,
190- unsigned char * A,
191- const float * absmax,
192- T* out,
193- long long blocksize,
194- long long n) {
195- if (blocksize <= 0 || n <= 0 ) return ;
156+ void dequantizeBlockwise8bitCpu (
157+ float * code, unsigned char * A, const float * absmax, T* out, long long blocksize, long long n
158+ ) {
159+ if (blocksize <= 0 || n <= 0 )
160+ return ;
196161 // 8-bit path
197162 BNB_OMP_PARALLEL_FOR
198163 for (long long block_idx = 0 ; block_idx < n; block_idx += blocksize) {
199164 long long valid_items = (n - block_idx >= blocksize ? blocksize : n - block_idx);
200- long long block_end = block_idx + valid_items;
165+ long long block_end = block_idx + valid_items;
201166 float scale = absmax[block_idx / blocksize];
202167 for (long long i = block_idx; i < block_end; ++i) {
203168 float v = code[A[i]] * scale;
@@ -212,7 +177,6 @@ void dequantizeBlockwise8bitCpu(float* code,
212177 }
213178}
214179
215-
216180void quantize_cpu (float * code, float * A, float * absmax, unsigned char * out, long long blocksize, long long n) {
217181
218182 // the default code is has range [-0.993, 1.0] which can cause an error in the binary search algorithm used below
@@ -265,26 +229,35 @@ void quantize_cpu(float* code, float* A, float* absmax, unsigned char* out, long
265229// ==============================================================
266230
267231template void dequantizeBlockwise8bitCpu<float >(
268- float * code, unsigned char * A, const float * absmax, float * out, long long blocksize, long long n);
232+ float * code, unsigned char * A, const float * absmax, float * out, long long blocksize, long long n
233+ );
269234template void dequantizeBlockwise8bitCpu<fp16_t >(
270- float * code, unsigned char * A, const float * absmax, fp16_t * out, long long blocksize, long long n);
235+ float * code, unsigned char * A, const float * absmax, fp16_t * out, long long blocksize, long long n
236+ );
271237template void dequantizeBlockwise8bitCpu<bf16_t >(
272- float * code, unsigned char * A, const float * absmax, bf16_t * out, long long blocksize, long long n);
238+ float * code, unsigned char * A, const float * absmax, bf16_t * out, long long blocksize, long long n
239+ );
273240
274241template void dequantizeBlockwise4bitCpu<float , FP4 >(
275- unsigned char * A, const float * absmax, float * out, long long blocksize, long long m, long long n);
242+ unsigned char * A, const float * absmax, float * out, long long blocksize, long long m, long long n
243+ );
276244template void dequantizeBlockwise4bitCpu<float , NF4 >(
277- unsigned char * A, const float * absmax, float * out, long long blocksize, long long m, long long n);
245+ unsigned char * A, const float * absmax, float * out, long long blocksize, long long m, long long n
246+ );
278247
279248template void dequantizeBlockwise4bitCpu<fp16_t , FP4 >(
280- unsigned char * A, const float * absmax, fp16_t * out, long long blocksize, long long m, long long n);
249+ unsigned char * A, const float * absmax, fp16_t * out, long long blocksize, long long m, long long n
250+ );
281251template void dequantizeBlockwise4bitCpu<fp16_t , NF4 >(
282- unsigned char * A, const float * absmax, fp16_t * out, long long blocksize, long long m, long long n);
252+ unsigned char * A, const float * absmax, fp16_t * out, long long blocksize, long long m, long long n
253+ );
283254
284255template void dequantizeBlockwise4bitCpu<bf16_t , FP4 >(
285- unsigned char * A, const float * absmax, bf16_t * out, long long blocksize, long long m, long long n);
256+ unsigned char * A, const float * absmax, bf16_t * out, long long blocksize, long long m, long long n
257+ );
286258template void dequantizeBlockwise4bitCpu<bf16_t , NF4 >(
287- unsigned char * A, const float * absmax, bf16_t * out, long long blocksize, long long m, long long n);
259+ unsigned char * A, const float * absmax, bf16_t * out, long long blocksize, long long m, long long n
260+ );
288261
289262// template void gemv_4bit_inference<fp16_t, 16>(
290263// int m, int n, int k, fp16_t* A, unsigned char* B, float* absmax, float* datatype, fp16_t* out,
0 commit comments