@@ -44,26 +44,59 @@ fn pad(p: usize, q: usize) -> usize {
4444}
4545
4646fn quantize_q8_1 (
47- src : & CudaView < f32 > ,
47+ src : & CudaSlice < f32 > ,
4848 dst : & mut CudaSlice < u8 > ,
49- elem_count : usize ,
49+ k : usize ,
5050 ky : usize ,
5151 dev : & CudaDevice ,
5252) -> Result < ( ) > {
53- let kx = elem_count;
54- let kx_padded = pad ( kx, MATRIX_ROW_PADDING ) ;
53+ let kx_padded = pad ( k, MATRIX_ROW_PADDING ) ;
5554 let num_blocks = ceil_div ( kx_padded, CUDA_QUANTIZE_BLOCK_SIZE ) ;
55+
56+ let total_rows = ky;
57+ // Get Q8_1 metadata.
58+ let q8_1_block_size = GgmlDType :: Q8_1 . block_size ( ) ;
59+ let q8_1_type_size = GgmlDType :: Q8_1 . type_size ( ) ;
60+
61+ // Calculate the size of the output buffer in bytes.
62+ let num_blocks_per_row = kx_padded / q8_1_block_size;
63+ let dst_row_size_bytes = num_blocks_per_row * q8_1_type_size;
64+
65+ const CHUNK_SIZE : usize = 65535 ; // gridDim.y limit
5666 let func = dev. get_or_load_func ( "quantize_q8_1" , & candle_kernels:: QUANTIZED ) ?;
57- let cfg = cudarc:: driver:: LaunchConfig {
58- grid_dim : ( num_blocks as u32 , ky as u32 , 1 ) ,
59- block_dim : ( CUDA_QUANTIZE_BLOCK_SIZE as u32 , 1 , 1 ) ,
60- shared_mem_bytes : 0 ,
61- } ;
62- let mut builder = func. builder ( ) ;
63- builder. arg ( src) ;
64- builder. arg ( dst) ;
65- barg ! ( builder, kx as i32 , kx_padded as i32 ) ;
66- unsafe { builder. launch ( cfg) } . w ( ) ?;
67+
68+ let mut rows_processed = 0 ;
69+ while rows_processed < total_rows {
70+ // --- calculate the number of rows for this chunk ---
71+ let remaining_rows = total_rows - rows_processed;
72+ // This is our gridDim.y, now <= 65535
73+ let rows_in_chunk = std:: cmp:: min ( CHUNK_SIZE , remaining_rows) ;
74+
75+ // --- slice the source (f32) tensor by elements ---
76+ let src_start_elem = rows_processed * k;
77+ let src_num_elems = rows_in_chunk * k;
78+ let src_chunk = src. slice ( src_start_elem..( src_start_elem + src_num_elems) ) ;
79+
80+ // --- slice the destination (u8) tensor by bytes ---
81+ let dst_start_byte = rows_processed * dst_row_size_bytes;
82+ let dst_num_bytes = rows_in_chunk * dst_row_size_bytes;
83+ let dst_chunk = dst. slice ( dst_start_byte..( dst_start_byte + dst_num_bytes) ) ;
84+
85+ let cfg = cudarc:: driver:: LaunchConfig {
86+ grid_dim : ( num_blocks as u32 , rows_in_chunk as u32 , 1 ) ,
87+ block_dim : ( CUDA_QUANTIZE_BLOCK_SIZE as u32 , 1 , 1 ) ,
88+ shared_mem_bytes : 0 ,
89+ } ;
90+
91+ let mut builder = func. builder ( ) ;
92+ builder. arg ( & src_chunk) ;
93+ builder. arg ( & dst_chunk) ;
94+ barg ! ( builder, k as i32 , kx_padded as i32 ) ;
95+ unsafe { builder. launch ( cfg) } . w ( ) ?;
96+
97+ rows_processed += rows_in_chunk;
98+ }
99+
67100 Ok ( ( ) )
68101}
69102
@@ -189,7 +222,7 @@ fn dequantize_f16(
189222
190223fn dequantize_mul_mat_vec (
191224 data : & PaddedCudaSlice ,
192- y : & CudaView < f32 > ,
225+ y : & CudaSlice < f32 > ,
193226 dtype : GgmlDType ,
194227 ncols : usize ,
195228 nrows : usize ,
@@ -235,7 +268,7 @@ fn dequantize_mul_mat_vec(
235268
236269fn mul_mat_vec_via_q8_1 (
237270 data : & PaddedCudaSlice ,
238- y : & CudaView < f32 > ,
271+ y : & CudaSlice < f32 > ,
239272 dtype : GgmlDType ,
240273 ncols : usize ,
241274 nrows : usize ,
@@ -306,7 +339,7 @@ fn mul_mat_vec_via_q8_1(
306339#[ allow( clippy:: too_many_arguments) ]
307340fn mul_mat_via_q8_1 (
308341 data : & PaddedCudaSlice ,
309- y : & CudaView < f32 > ,
342+ y : & CudaSlice < f32 > ,
310343 dtype : GgmlDType ,
311344 x_rows : usize ,
312345 x_cols : usize ,
@@ -377,7 +410,7 @@ fn indexed_moe_forward_fused_q8_1_input(
377410 weight : & CudaView < u8 > ,
378411 w_shape : & crate :: Shape , //[num_experts, n, k]
379412 w_dtype : GgmlDType ,
380- input : & CudaView < f32 > ,
413+ input : & CudaSlice < f32 > ,
381414 in_shape : & crate :: Shape , //[batch, topk or 1, k]
382415 ids : & CudaView < u32 > ,
383416 idx_shape : & crate :: Shape , //[batch, topk]
@@ -391,11 +424,19 @@ fn indexed_moe_forward_fused_q8_1_input(
391424 assert ! ( batch == idx_shape. dims( ) [ 0 ] , "batch dim not match!" ) ;
392425
393426 //quant input into q8_1
427+ let total_rows = batch * input_dim1;
394428 let k_padded = pad ( k, MATRIX_ROW_PADDING ) ;
395- let y_size_in_bytes =
396- batch * input_dim1 * k_padded * GgmlDType :: Q8_1 . type_size ( ) / GgmlDType :: Q8_1 . block_size ( ) ;
429+ // Get Q8_1 metadata.
430+ let q8_1_block_size = GgmlDType :: Q8_1 . block_size ( ) ;
431+ let q8_1_type_size = GgmlDType :: Q8_1 . type_size ( ) ;
432+
433+ // Calculate the size of the output buffer in bytes.
434+ let num_blocks_per_row = k_padded / q8_1_block_size;
435+ let dst_row_size_bytes = num_blocks_per_row * q8_1_type_size;
436+ let y_size_in_bytes = total_rows * dst_row_size_bytes;
397437 let mut input_quant = unsafe { dev. alloc :: < u8 > ( y_size_in_bytes) ? } ;
398- quantize_q8_1 ( input, & mut input_quant, k, batch * input_dim1, dev) ?;
438+
439+ quantize_q8_1 ( & input, & mut input_quant, k, total_rows, dev) ?;
399440
400441 // output buffer
401442 let outsize = batch * topk * n;
@@ -469,7 +510,7 @@ impl QCudaStorage {
469510 & self . data . inner . slice ( 0 ..) ,
470511 self_shape, //[num_experts, n, k]
471512 self . dtype ( ) ,
472- & input_storage. slice ( 0 .. ) ,
513+ & input_storage,
473514 input_l. shape ( ) , //[batch, topk or 1, k]
474515 & ids_storage. slice ( 0 ..) ,
475516 ids_l. shape ( ) , //[batch, topk]
@@ -711,8 +752,11 @@ impl QCudaStorage {
711752 ) -> Result < ( CudaStorage , crate :: Shape ) > {
712753 let ( nrows, ncols) = self_shape. dims2 ( ) ?;
713754 let rhs = rhs. as_cuda_slice :: < f32 > ( ) ?;
714- let rhs = match rhs_l. contiguous_offsets ( ) {
715- Some ( ( o1, o2) ) => rhs. slice ( o1..o2) ,
755+ match rhs_l. contiguous_offsets ( ) {
756+ Some ( ( o1, _) ) => assert ! (
757+ o1 == 0 ,
758+ "sliced input is not supported in quantized matmul!"
759+ ) ,
716760 None => Err ( crate :: Error :: RequiresContiguous { op : "dmmv" } . bt ( ) ) ?,
717761 } ;
718762 let ( b_size, k) = match rhs_l. shape ( ) . dims ( ) {
@@ -766,8 +810,11 @@ impl QCudaStorage {
766810 storage. matmul ( & data_f32, ( b, m, n, k) , layout, & rhs_l) ?
767811 } else {
768812 let storage = storage. as_cuda_slice :: < f32 > ( ) ?;
769- let storage = match layout. contiguous_offsets ( ) {
770- Some ( ( o1, o2) ) => storage. slice ( o1..o2) ,
813+ match layout. contiguous_offsets ( ) {
814+ Some ( ( o1, _) ) => assert ! (
815+ o1 == 0 ,
816+ "sliced input is not supported in quantized matmul!"
817+ ) ,
771818 None => Err ( crate :: Error :: RequiresContiguous {
772819 op : "quantized-matmul" ,
773820 }
@@ -826,7 +873,7 @@ mod test {
826873 let mut y_q8_1 = unsafe { dev. alloc :: < u8 > ( y_size_in_bytes) ? } ;
827874 let vs: Vec < f32 > = ( 0 ..el) . map ( |v| v as f32 ) . collect ( ) ;
828875 let y = dev. memcpy_stod ( & vs) ?;
829- quantize_q8_1 ( & y. slice ( .. ) , & mut y_q8_1, el, 1 , & dev) ?;
876+ quantize_q8_1 ( & y, & mut y_q8_1, el, 1 , & dev) ?;
830877 Ok ( ( ) )
831878 }
832879
@@ -840,7 +887,7 @@ mod test {
840887 xs. quantize ( & CudaStorage :: wrap_cuda_slice ( y. clone ( ) , dev. clone ( ) ) ) ?;
841888 let cuda_storage = mul_mat_vec_via_q8_1 (
842889 & xs. data ,
843- & y. slice ( .. ) ,
890+ & y,
844891 /* dtype */ GgmlDType :: Q4_0 ,
845892 /* ncols */ ncols,
846893 /* nrows */ 1 ,
@@ -856,7 +903,7 @@ mod test {
856903
857904 let cuda_storage = dequantize_mul_mat_vec (
858905 & xs. data ,
859- & y. slice ( .. ) ,
906+ & y,
860907 /* dtype */ GgmlDType :: Q4_0 ,
861908 /* ncols */ ncols,
862909 /* nrows */ 1 ,
@@ -879,7 +926,7 @@ mod test {
879926 xs. quantize ( & CudaStorage :: wrap_cuda_slice ( y. clone ( ) , dev. clone ( ) ) ) ?;
880927 let cuda_storage = mul_mat_via_q8_1 (
881928 & xs. data ,
882- & y. slice ( .. ) ,
929+ & y,
883930 /* dtype */ GgmlDType :: Q4_0 ,
884931 /* x_rows */ 4 ,
885932 /* x_cols */ ncols,
@@ -920,7 +967,7 @@ mod test {
920967 xs. quantize ( & CudaStorage :: wrap_cuda_slice ( y. clone ( ) , dev. clone ( ) ) ) ?;
921968 let cuda_storage = mul_mat_via_q8_1 (
922969 & xs. data ,
923- & y. slice ( .. ) ,
970+ & y,
924971 /* dtype */ GgmlDType :: Q4_0 ,
925972 /* x_rows */ x_rows,
926973 /* x_cols */ ncols,
0 commit comments