1use arrayref::{array_mut_ref, array_ref};
17use core::mem::{MaybeUninit, size_of};
18
19mod bitpacker_internal;
20
21pub use bitpacker_internal::{BitPacker, BitPacker4x, BitPacker8x};
22
23pub const FL_ORDER: [usize; 8] = [0, 4, 2, 6, 1, 5, 3, 7];
24
25pub trait FastLanes: Sized + Copy {
26 const T: usize = size_of::<Self>() * 8;
27 const LANES: usize = 1024 / Self::T;
28}
29
30impl FastLanes for u8 {}
32impl FastLanes for u16 {}
33impl FastLanes for u32 {}
34impl FastLanes for u64 {}
35
36macro_rules! pack {
37 ($T:ty, $W:expr, $packed:expr, $lane:expr, | $_1:tt $idx:ident | $($body:tt)*) => {
38 macro_rules! __kernel__ {( $_1 $idx:ident ) => ( $($body)* )}
39 {
40 use paste::paste;
41
42 const T: usize = <$T>::T;
44
45 #[inline(always)]
46 fn index(row: usize, lane: usize) -> usize {
47 let o = row / 8;
48 let s = row % 8;
49 (FL_ORDER[o] * 16) + (s * 128) + lane
50 }
51
52 if $W == 0 {
53 } else if $W == T {
55 paste!(seq_t!(row in $T {
57 let idx = index(row, $lane);
58 $packed[<$T>::LANES * row + $lane].write(__kernel__!(idx));
59 }));
60 } else {
61 let mask: $T = (1 << $W) - 1;
63
64 let mut tmp: $T = 0;
66
67 paste!(seq_t!(row in $T {
71 let idx = index(row, $lane);
72 let src = __kernel__!(idx);
73 let src = src & mask;
74
75 if row == 0 {
77 tmp = src;
78 } else {
79 tmp |= src << (row * $W) % T;
80 }
81
82 let curr_word: usize = (row * $W) / T;
85 let next_word: usize = ((row + 1) * $W) / T;
86
87 #[allow(unused_assignments)]
88 if next_word > curr_word {
89 $packed[<$T>::LANES * curr_word + $lane].write(tmp);
90 let remaining_bits: usize = ((row + 1) * $W) % T;
91 tmp = src >> $W - remaining_bits;
93 }
94 }));
95 }
96 }
97 };
98}
99
100macro_rules! unpack {
101 ($T:ty, $W:expr, $packed:expr, $lane:expr, | $_1:tt $idx:ident, $_2:tt $elem:ident | $($body:tt)*) => {
102 macro_rules! __kernel__ {( $_1 $idx:ident, $_2 $elem:ident ) => ( $($body)* )}
103 {
104 use paste::paste;
105
106 const T: usize = <$T>::T;
108
109 #[inline(always)]
110 fn index(row: usize, lane: usize) -> usize {
111 let o = row / 8;
112 let s = row % 8;
113 (FL_ORDER[o] * 16) + (s * 128) + lane
114 }
115
116 if $W == 0 {
117 paste!(seq_t!(row in $T {
120 let idx = index(row, $lane);
121 let zero: $T = 0;
122 __kernel__!(idx, zero);
123 }));
124 } else if $W == T {
125 paste!(seq_t!(row in $T {
127 let idx = index(row, $lane);
128 let src = $packed[<$T>::LANES * row + $lane];
129 __kernel__!(idx, src);
130 }));
131 } else {
132 #[inline]
133 fn mask(width: usize) -> $T {
134 if width == T { <$T>::MAX } else { (1 << (width % T)) - 1 }
135 }
136
137 let mut src: $T = $packed[$lane];
138 let mut tmp: $T;
139
140 paste!(seq_t!(row in $T {
141 let curr_word: usize = (row * $W) / T;
143 let next_word = ((row + 1) * $W) / T;
144
145 let shift = (row * $W) % T;
146
147 if next_word > curr_word {
148 let remaining_bits = ((row + 1) * $W) % T;
151 let current_bits = $W - remaining_bits;
152 tmp = (src >> shift) & mask(current_bits);
153
154 if next_word < $W {
155 src = $packed[<$T>::LANES * next_word + $lane];
157 tmp |= (src & mask(remaining_bits)) << current_bits;
159 }
160 } else {
161 tmp = (src >> shift) & mask($W);
163 }
164
165 let idx = index(row, $lane);
167 __kernel__!(idx, tmp);
168 }));
169 }
170 }
171 };
172}
173
174macro_rules! seq_t {
176 ($ident:ident in u8 $body:tt) => {seq_macro::seq!($ident in 0..8 $body)};
177 ($ident:ident in u16 $body:tt) => {seq_macro::seq!($ident in 0..16 $body)};
178 ($ident:ident in u32 $body:tt) => {seq_macro::seq!($ident in 0..32 $body)};
179 ($ident:ident in u64 $body:tt) => {seq_macro::seq!($ident in 0..64 $body)};
180}
181
182pub trait BitPacking: FastLanes {
184 unsafe fn unchecked_pack(width: usize, input: &[Self], output: &mut [Self]);
192
193 unsafe fn unchecked_unpack(width: usize, input: &[Self], output: &mut [Self]);
201}
202
203pub trait BitPackingUninit: BitPacking {
205 unsafe fn unchecked_pack_uninit(width: usize, input: &[Self], output: &mut [MaybeUninit<Self>]);
211
212 unsafe fn unchecked_unpack_uninit(
218 width: usize,
219 input: &[Self],
220 output: &mut [MaybeUninit<Self>],
221 );
222}
223
224macro_rules! impl_bitpacking_compat {
225 ($ty:ty) => {
226 impl BitPacking for $ty {
227 unsafe fn unchecked_pack(width: usize, input: &[Self], output: &mut [Self]) {
228 let output = unsafe {
229 core::slice::from_raw_parts_mut(
230 output.as_mut_ptr().cast::<MaybeUninit<Self>>(),
231 output.len(),
232 )
233 };
234 unsafe { <Self as BitPackingUninit>::unchecked_pack_uninit(width, input, output) };
235 }
236
237 unsafe fn unchecked_unpack(width: usize, input: &[Self], output: &mut [Self]) {
238 let output = unsafe {
239 core::slice::from_raw_parts_mut(
240 output.as_mut_ptr().cast::<MaybeUninit<Self>>(),
241 output.len(),
242 )
243 };
244 unsafe {
245 <Self as BitPackingUninit>::unchecked_unpack_uninit(width, input, output)
246 };
247 }
248 }
249 };
250}
251
252impl_bitpacking_compat!(u8);
253impl_bitpacking_compat!(u16);
254impl_bitpacking_compat!(u32);
255impl_bitpacking_compat!(u64);
256
257impl BitPackingUninit for u8 {
258 unsafe fn unchecked_pack_uninit(
259 width: usize,
260 input: &[Self],
261 output: &mut [MaybeUninit<Self>],
262 ) {
263 let packed_len = 128 * width / size_of::<Self>();
264 debug_assert_eq!(
265 output.len(),
266 packed_len,
267 "Output buffer must be of size 1024 * W / T"
268 );
269 debug_assert_eq!(input.len(), 1024, "Input buffer must be of size 1024");
270 debug_assert!(
271 width <= Self::T,
272 "Width must be less than or equal to {}",
273 Self::T
274 );
275
276 match width {
277 0 => {
278 }
280 1 => pack_8_1(
281 array_ref![input, 0, 1024],
282 array_mut_ref![output, 0, 1024 / 8],
283 ),
284 2 => pack_8_2(
285 array_ref![input, 0, 1024],
286 array_mut_ref![output, 0, 1024 * 2 / 8],
287 ),
288 3 => pack_8_3(
289 array_ref![input, 0, 1024],
290 array_mut_ref![output, 0, 1024 * 3 / 8],
291 ),
292 4 => pack_8_4(
293 array_ref![input, 0, 1024],
294 array_mut_ref![output, 0, 1024 * 4 / 8],
295 ),
296 5 => pack_8_5(
297 array_ref![input, 0, 1024],
298 array_mut_ref![output, 0, 1024 * 5 / 8],
299 ),
300 6 => pack_8_6(
301 array_ref![input, 0, 1024],
302 array_mut_ref![output, 0, 1024 * 6 / 8],
303 ),
304 7 => pack_8_7(
305 array_ref![input, 0, 1024],
306 array_mut_ref![output, 0, 1024 * 7 / 8],
307 ),
308 8 => pack_8_8(
309 array_ref![input, 0, 1024],
310 array_mut_ref![output, 0, 1024 * 8 / 8],
311 ),
312
313 _ => unreachable!("Unsupported width: {}", width),
314 }
315 }
316
317 unsafe fn unchecked_unpack_uninit(
318 width: usize,
319 input: &[Self],
320 output: &mut [MaybeUninit<Self>],
321 ) {
322 let packed_len = 128 * width / size_of::<Self>();
323 debug_assert_eq!(
324 input.len(),
325 packed_len,
326 "Input buffer must be of size 1024 * W / T"
327 );
328 debug_assert_eq!(output.len(), 1024, "Output buffer must be of size 1024");
329 debug_assert!(
330 width <= Self::T,
331 "Width must be less than or equal to {}",
332 Self::T
333 );
334
335 match width {
336 0 => {
337 output.fill(MaybeUninit::new(0));
339 }
340 1 => unpack_8_1(
341 array_ref![input, 0, 1024 / 8],
342 array_mut_ref![output, 0, 1024],
343 ),
344 2 => unpack_8_2(
345 array_ref![input, 0, 1024 * 2 / 8],
346 array_mut_ref![output, 0, 1024],
347 ),
348 3 => unpack_8_3(
349 array_ref![input, 0, 1024 * 3 / 8],
350 array_mut_ref![output, 0, 1024],
351 ),
352 4 => unpack_8_4(
353 array_ref![input, 0, 1024 * 4 / 8],
354 array_mut_ref![output, 0, 1024],
355 ),
356 5 => unpack_8_5(
357 array_ref![input, 0, 1024 * 5 / 8],
358 array_mut_ref![output, 0, 1024],
359 ),
360 6 => unpack_8_6(
361 array_ref![input, 0, 1024 * 6 / 8],
362 array_mut_ref![output, 0, 1024],
363 ),
364 7 => unpack_8_7(
365 array_ref![input, 0, 1024 * 7 / 8],
366 array_mut_ref![output, 0, 1024],
367 ),
368 8 => unpack_8_8(
369 array_ref![input, 0, 1024 * 8 / 8],
370 array_mut_ref![output, 0, 1024],
371 ),
372
373 _ => unreachable!("Unsupported width: {}", width),
374 }
375 }
376}
377
378impl BitPackingUninit for u16 {
379 unsafe fn unchecked_pack_uninit(
380 width: usize,
381 input: &[Self],
382 output: &mut [MaybeUninit<Self>],
383 ) {
384 let packed_len = 128 * width / size_of::<Self>();
385 debug_assert_eq!(
386 output.len(),
387 packed_len,
388 "Output buffer must be of size 1024 * W / T"
389 );
390 debug_assert_eq!(input.len(), 1024, "Input buffer must be of size 1024");
391 debug_assert!(
392 width <= Self::T,
393 "Width must be less than or equal to {}",
394 Self::T
395 );
396
397 match width {
398 0 => {
399 }
401 1 => pack_16_1(
402 array_ref![input, 0, 1024],
403 array_mut_ref![output, 0, 1024 / 16],
404 ),
405 2 => pack_16_2(
406 array_ref![input, 0, 1024],
407 array_mut_ref![output, 0, 1024 * 2 / 16],
408 ),
409 3 => pack_16_3(
410 array_ref![input, 0, 1024],
411 array_mut_ref![output, 0, 1024 * 3 / 16],
412 ),
413 4 => pack_16_4(
414 array_ref![input, 0, 1024],
415 array_mut_ref![output, 0, 1024 * 4 / 16],
416 ),
417 5 => pack_16_5(
418 array_ref![input, 0, 1024],
419 array_mut_ref![output, 0, 1024 * 5 / 16],
420 ),
421 6 => pack_16_6(
422 array_ref![input, 0, 1024],
423 array_mut_ref![output, 0, 1024 * 6 / 16],
424 ),
425 7 => pack_16_7(
426 array_ref![input, 0, 1024],
427 array_mut_ref![output, 0, 1024 * 7 / 16],
428 ),
429 8 => pack_16_8(
430 array_ref![input, 0, 1024],
431 array_mut_ref![output, 0, 1024 * 8 / 16],
432 ),
433 9 => pack_16_9(
434 array_ref![input, 0, 1024],
435 array_mut_ref![output, 0, 1024 * 9 / 16],
436 ),
437
438 10 => pack_16_10(
439 array_ref![input, 0, 1024],
440 array_mut_ref![output, 0, 1024 * 10 / 16],
441 ),
442 11 => pack_16_11(
443 array_ref![input, 0, 1024],
444 array_mut_ref![output, 0, 1024 * 11 / 16],
445 ),
446 12 => pack_16_12(
447 array_ref![input, 0, 1024],
448 array_mut_ref![output, 0, 1024 * 12 / 16],
449 ),
450 13 => pack_16_13(
451 array_ref![input, 0, 1024],
452 array_mut_ref![output, 0, 1024 * 13 / 16],
453 ),
454 14 => pack_16_14(
455 array_ref![input, 0, 1024],
456 array_mut_ref![output, 0, 1024 * 14 / 16],
457 ),
458 15 => pack_16_15(
459 array_ref![input, 0, 1024],
460 array_mut_ref![output, 0, 1024 * 15 / 16],
461 ),
462 16 => pack_16_16(
463 array_ref![input, 0, 1024],
464 array_mut_ref![output, 0, 1024 * 16 / 16],
465 ),
466
467 _ => unreachable!("Unsupported width: {}", width),
468 }
469 }
470
471 unsafe fn unchecked_unpack_uninit(
472 width: usize,
473 input: &[Self],
474 output: &mut [MaybeUninit<Self>],
475 ) {
476 let packed_len = 128 * width / size_of::<Self>();
477 debug_assert_eq!(
478 input.len(),
479 packed_len,
480 "Input buffer must be of size 1024 * W / T"
481 );
482 debug_assert_eq!(output.len(), 1024, "Output buffer must be of size 1024");
483 debug_assert!(
484 width <= Self::T,
485 "Width must be less than or equal to {}",
486 Self::T
487 );
488
489 match width {
490 0 => {
491 output.fill(MaybeUninit::new(0));
492 }
493 1 => unpack_16_1(
494 array_ref![input, 0, 1024 / 16],
495 array_mut_ref![output, 0, 1024],
496 ),
497 2 => unpack_16_2(
498 array_ref![input, 0, 1024 * 2 / 16],
499 array_mut_ref![output, 0, 1024],
500 ),
501 3 => unpack_16_3(
502 array_ref![input, 0, 1024 * 3 / 16],
503 array_mut_ref![output, 0, 1024],
504 ),
505 4 => unpack_16_4(
506 array_ref![input, 0, 1024 * 4 / 16],
507 array_mut_ref![output, 0, 1024],
508 ),
509 5 => unpack_16_5(
510 array_ref![input, 0, 1024 * 5 / 16],
511 array_mut_ref![output, 0, 1024],
512 ),
513 6 => unpack_16_6(
514 array_ref![input, 0, 1024 * 6 / 16],
515 array_mut_ref![output, 0, 1024],
516 ),
517 7 => unpack_16_7(
518 array_ref![input, 0, 1024 * 7 / 16],
519 array_mut_ref![output, 0, 1024],
520 ),
521 8 => unpack_16_8(
522 array_ref![input, 0, 1024 * 8 / 16],
523 array_mut_ref![output, 0, 1024],
524 ),
525 9 => unpack_16_9(
526 array_ref![input, 0, 1024 * 9 / 16],
527 array_mut_ref![output, 0, 1024],
528 ),
529
530 10 => unpack_16_10(
531 array_ref![input, 0, 1024 * 10 / 16],
532 array_mut_ref![output, 0, 1024],
533 ),
534 11 => unpack_16_11(
535 array_ref![input, 0, 1024 * 11 / 16],
536 array_mut_ref![output, 0, 1024],
537 ),
538 12 => unpack_16_12(
539 array_ref![input, 0, 1024 * 12 / 16],
540 array_mut_ref![output, 0, 1024],
541 ),
542 13 => unpack_16_13(
543 array_ref![input, 0, 1024 * 13 / 16],
544 array_mut_ref![output, 0, 1024],
545 ),
546 14 => unpack_16_14(
547 array_ref![input, 0, 1024 * 14 / 16],
548 array_mut_ref![output, 0, 1024],
549 ),
550 15 => unpack_16_15(
551 array_ref![input, 0, 1024 * 15 / 16],
552 array_mut_ref![output, 0, 1024],
553 ),
554 16 => unpack_16_16(
555 array_ref![input, 0, 1024 * 16 / 16],
556 array_mut_ref![output, 0, 1024],
557 ),
558
559 _ => unreachable!("Unsupported width: {}", width),
560 }
561 }
562}
563
564impl BitPackingUninit for u32 {
565 unsafe fn unchecked_pack_uninit(
566 width: usize,
567 input: &[Self],
568 output: &mut [MaybeUninit<Self>],
569 ) {
570 let packed_len = 128 * width / size_of::<Self>();
571 debug_assert_eq!(
572 output.len(),
573 packed_len,
574 "Output buffer must be of size 1024 * W / T"
575 );
576 debug_assert_eq!(input.len(), 1024, "Input buffer must be of size 1024");
577 debug_assert!(
578 width <= Self::T,
579 "Width must be less than or equal to {}",
580 Self::T
581 );
582
583 match width {
584 0 => {
585 }
587 1 => pack_32_1(
588 array_ref![input, 0, 1024],
589 array_mut_ref![output, 0, 1024 / 32],
590 ),
591 2 => pack_32_2(
592 array_ref![input, 0, 1024],
593 array_mut_ref![output, 0, 1024 * 2 / 32],
594 ),
595 3 => pack_32_3(
596 array_ref![input, 0, 1024],
597 array_mut_ref![output, 0, 1024 * 3 / 32],
598 ),
599 4 => pack_32_4(
600 array_ref![input, 0, 1024],
601 array_mut_ref![output, 0, 1024 * 4 / 32],
602 ),
603 5 => pack_32_5(
604 array_ref![input, 0, 1024],
605 array_mut_ref![output, 0, 1024 * 5 / 32],
606 ),
607 6 => pack_32_6(
608 array_ref![input, 0, 1024],
609 array_mut_ref![output, 0, 1024 * 6 / 32],
610 ),
611 7 => pack_32_7(
612 array_ref![input, 0, 1024],
613 array_mut_ref![output, 0, 1024 * 7 / 32],
614 ),
615 8 => pack_32_8(
616 array_ref![input, 0, 1024],
617 array_mut_ref![output, 0, 1024 * 8 / 32],
618 ),
619 9 => pack_32_9(
620 array_ref![input, 0, 1024],
621 array_mut_ref![output, 0, 1024 * 9 / 32],
622 ),
623
624 10 => pack_32_10(
625 array_ref![input, 0, 1024],
626 array_mut_ref![output, 0, 1024 * 10 / 32],
627 ),
628 11 => pack_32_11(
629 array_ref![input, 0, 1024],
630 array_mut_ref![output, 0, 1024 * 11 / 32],
631 ),
632 12 => pack_32_12(
633 array_ref![input, 0, 1024],
634 array_mut_ref![output, 0, 1024 * 12 / 32],
635 ),
636 13 => pack_32_13(
637 array_ref![input, 0, 1024],
638 array_mut_ref![output, 0, 1024 * 13 / 32],
639 ),
640 14 => pack_32_14(
641 array_ref![input, 0, 1024],
642 array_mut_ref![output, 0, 1024 * 14 / 32],
643 ),
644 15 => pack_32_15(
645 array_ref![input, 0, 1024],
646 array_mut_ref![output, 0, 1024 * 15 / 32],
647 ),
648 16 => pack_32_16(
649 array_ref![input, 0, 1024],
650 array_mut_ref![output, 0, 1024 * 16 / 32],
651 ),
652 17 => pack_32_17(
653 array_ref![input, 0, 1024],
654 array_mut_ref![output, 0, 1024 * 17 / 32],
655 ),
656 18 => pack_32_18(
657 array_ref![input, 0, 1024],
658 array_mut_ref![output, 0, 1024 * 18 / 32],
659 ),
660 19 => pack_32_19(
661 array_ref![input, 0, 1024],
662 array_mut_ref![output, 0, 1024 * 19 / 32],
663 ),
664
665 20 => pack_32_20(
666 array_ref![input, 0, 1024],
667 array_mut_ref![output, 0, 1024 * 20 / 32],
668 ),
669 21 => pack_32_21(
670 array_ref![input, 0, 1024],
671 array_mut_ref![output, 0, 1024 * 21 / 32],
672 ),
673 22 => pack_32_22(
674 array_ref![input, 0, 1024],
675 array_mut_ref![output, 0, 1024 * 22 / 32],
676 ),
677 23 => pack_32_23(
678 array_ref![input, 0, 1024],
679 array_mut_ref![output, 0, 1024 * 23 / 32],
680 ),
681 24 => pack_32_24(
682 array_ref![input, 0, 1024],
683 array_mut_ref![output, 0, 1024 * 24 / 32],
684 ),
685 25 => pack_32_25(
686 array_ref![input, 0, 1024],
687 array_mut_ref![output, 0, 1024 * 25 / 32],
688 ),
689 26 => pack_32_26(
690 array_ref![input, 0, 1024],
691 array_mut_ref![output, 0, 1024 * 26 / 32],
692 ),
693 27 => pack_32_27(
694 array_ref![input, 0, 1024],
695 array_mut_ref![output, 0, 1024 * 27 / 32],
696 ),
697 28 => pack_32_28(
698 array_ref![input, 0, 1024],
699 array_mut_ref![output, 0, 1024 * 28 / 32],
700 ),
701 29 => pack_32_29(
702 array_ref![input, 0, 1024],
703 array_mut_ref![output, 0, 1024 * 29 / 32],
704 ),
705
706 30 => pack_32_30(
707 array_ref![input, 0, 1024],
708 array_mut_ref![output, 0, 1024 * 30 / 32],
709 ),
710 31 => pack_32_31(
711 array_ref![input, 0, 1024],
712 array_mut_ref![output, 0, 1024 * 31 / 32],
713 ),
714 32 => pack_32_32(
715 array_ref![input, 0, 1024],
716 array_mut_ref![output, 0, 1024 * 32 / 32],
717 ),
718
719 _ => unreachable!("Unsupported width: {}", width),
720 }
721 }
722
723 unsafe fn unchecked_unpack_uninit(
724 width: usize,
725 input: &[Self],
726 output: &mut [MaybeUninit<Self>],
727 ) {
728 let packed_len = 128 * width / size_of::<Self>();
729 debug_assert_eq!(
730 input.len(),
731 packed_len,
732 "Input buffer must be of size 1024 * W / T"
733 );
734 debug_assert_eq!(output.len(), 1024, "Output buffer must be of size 1024");
735 debug_assert!(
736 width <= Self::T,
737 "Width must be less than or equal to {}",
738 Self::T
739 );
740
741 match width {
742 0 => {
743 output.fill(MaybeUninit::new(0));
744 }
745 1 => unpack_32_1(
746 array_ref![input, 0, 1024 / 32],
747 array_mut_ref![output, 0, 1024],
748 ),
749 2 => unpack_32_2(
750 array_ref![input, 0, 1024 * 2 / 32],
751 array_mut_ref![output, 0, 1024],
752 ),
753 3 => unpack_32_3(
754 array_ref![input, 0, 1024 * 3 / 32],
755 array_mut_ref![output, 0, 1024],
756 ),
757 4 => unpack_32_4(
758 array_ref![input, 0, 1024 * 4 / 32],
759 array_mut_ref![output, 0, 1024],
760 ),
761 5 => unpack_32_5(
762 array_ref![input, 0, 1024 * 5 / 32],
763 array_mut_ref![output, 0, 1024],
764 ),
765 6 => unpack_32_6(
766 array_ref![input, 0, 1024 * 6 / 32],
767 array_mut_ref![output, 0, 1024],
768 ),
769 7 => unpack_32_7(
770 array_ref![input, 0, 1024 * 7 / 32],
771 array_mut_ref![output, 0, 1024],
772 ),
773 8 => unpack_32_8(
774 array_ref![input, 0, 1024 * 8 / 32],
775 array_mut_ref![output, 0, 1024],
776 ),
777 9 => unpack_32_9(
778 array_ref![input, 0, 1024 * 9 / 32],
779 array_mut_ref![output, 0, 1024],
780 ),
781
782 10 => unpack_32_10(
783 array_ref![input, 0, 1024 * 10 / 32],
784 array_mut_ref![output, 0, 1024],
785 ),
786 11 => unpack_32_11(
787 array_ref![input, 0, 1024 * 11 / 32],
788 array_mut_ref![output, 0, 1024],
789 ),
790 12 => unpack_32_12(
791 array_ref![input, 0, 1024 * 12 / 32],
792 array_mut_ref![output, 0, 1024],
793 ),
794 13 => unpack_32_13(
795 array_ref![input, 0, 1024 * 13 / 32],
796 array_mut_ref![output, 0, 1024],
797 ),
798 14 => unpack_32_14(
799 array_ref![input, 0, 1024 * 14 / 32],
800 array_mut_ref![output, 0, 1024],
801 ),
802 15 => unpack_32_15(
803 array_ref![input, 0, 1024 * 15 / 32],
804 array_mut_ref![output, 0, 1024],
805 ),
806 16 => unpack_32_16(
807 array_ref![input, 0, 1024 * 16 / 32],
808 array_mut_ref![output, 0, 1024],
809 ),
810 17 => unpack_32_17(
811 array_ref![input, 0, 1024 * 17 / 32],
812 array_mut_ref![output, 0, 1024],
813 ),
814 18 => unpack_32_18(
815 array_ref![input, 0, 1024 * 18 / 32],
816 array_mut_ref![output, 0, 1024],
817 ),
818 19 => unpack_32_19(
819 array_ref![input, 0, 1024 * 19 / 32],
820 array_mut_ref![output, 0, 1024],
821 ),
822
823 20 => unpack_32_20(
824 array_ref![input, 0, 1024 * 20 / 32],
825 array_mut_ref![output, 0, 1024],
826 ),
827 21 => unpack_32_21(
828 array_ref![input, 0, 1024 * 21 / 32],
829 array_mut_ref![output, 0, 1024],
830 ),
831 22 => unpack_32_22(
832 array_ref![input, 0, 1024 * 22 / 32],
833 array_mut_ref![output, 0, 1024],
834 ),
835 23 => unpack_32_23(
836 array_ref![input, 0, 1024 * 23 / 32],
837 array_mut_ref![output, 0, 1024],
838 ),
839 24 => unpack_32_24(
840 array_ref![input, 0, 1024 * 24 / 32],
841 array_mut_ref![output, 0, 1024],
842 ),
843 25 => unpack_32_25(
844 array_ref![input, 0, 1024 * 25 / 32],
845 array_mut_ref![output, 0, 1024],
846 ),
847 26 => unpack_32_26(
848 array_ref![input, 0, 1024 * 26 / 32],
849 array_mut_ref![output, 0, 1024],
850 ),
851 27 => unpack_32_27(
852 array_ref![input, 0, 1024 * 27 / 32],
853 array_mut_ref![output, 0, 1024],
854 ),
855 28 => unpack_32_28(
856 array_ref![input, 0, 1024 * 28 / 32],
857 array_mut_ref![output, 0, 1024],
858 ),
859 29 => unpack_32_29(
860 array_ref![input, 0, 1024 * 29 / 32],
861 array_mut_ref![output, 0, 1024],
862 ),
863
864 30 => unpack_32_30(
865 array_ref![input, 0, 1024 * 30 / 32],
866 array_mut_ref![output, 0, 1024],
867 ),
868 31 => unpack_32_31(
869 array_ref![input, 0, 1024 * 31 / 32],
870 array_mut_ref![output, 0, 1024],
871 ),
872 32 => unpack_32_32(
873 array_ref![input, 0, 1024 * 32 / 32],
874 array_mut_ref![output, 0, 1024],
875 ),
876
877 _ => unreachable!("Unsupported width: {}", width),
878 }
879 }
880}
881
882impl BitPackingUninit for u64 {
883 unsafe fn unchecked_pack_uninit(
884 width: usize,
885 input: &[Self],
886 output: &mut [MaybeUninit<Self>],
887 ) {
888 let packed_len = 128 * width / size_of::<Self>();
889 debug_assert_eq!(
890 output.len(),
891 packed_len,
892 "Output buffer must be of size 1024 * W / T"
893 );
894 debug_assert_eq!(input.len(), 1024, "Input buffer must be of size 1024");
895 debug_assert!(
896 width <= Self::T,
897 "Width must be less than or equal to {}",
898 Self::T
899 );
900
901 match width {
902 0 => {
903 }
905 1 => pack_64_1(
906 array_ref![input, 0, 1024],
907 array_mut_ref![output, 0, 1024 / 64],
908 ),
909 2 => pack_64_2(
910 array_ref![input, 0, 1024],
911 array_mut_ref![output, 0, 1024 * 2 / 64],
912 ),
913 3 => pack_64_3(
914 array_ref![input, 0, 1024],
915 array_mut_ref![output, 0, 1024 * 3 / 64],
916 ),
917 4 => pack_64_4(
918 array_ref![input, 0, 1024],
919 array_mut_ref![output, 0, 1024 * 4 / 64],
920 ),
921 5 => pack_64_5(
922 array_ref![input, 0, 1024],
923 array_mut_ref![output, 0, 1024 * 5 / 64],
924 ),
925 6 => pack_64_6(
926 array_ref![input, 0, 1024],
927 array_mut_ref![output, 0, 1024 * 6 / 64],
928 ),
929 7 => pack_64_7(
930 array_ref![input, 0, 1024],
931 array_mut_ref![output, 0, 1024 * 7 / 64],
932 ),
933 8 => pack_64_8(
934 array_ref![input, 0, 1024],
935 array_mut_ref![output, 0, 1024 * 8 / 64],
936 ),
937 9 => pack_64_9(
938 array_ref![input, 0, 1024],
939 array_mut_ref![output, 0, 1024 * 9 / 64],
940 ),
941
942 10 => pack_64_10(
943 array_ref![input, 0, 1024],
944 array_mut_ref![output, 0, 1024 * 10 / 64],
945 ),
946 11 => pack_64_11(
947 array_ref![input, 0, 1024],
948 array_mut_ref![output, 0, 1024 * 11 / 64],
949 ),
950 12 => pack_64_12(
951 array_ref![input, 0, 1024],
952 array_mut_ref![output, 0, 1024 * 12 / 64],
953 ),
954 13 => pack_64_13(
955 array_ref![input, 0, 1024],
956 array_mut_ref![output, 0, 1024 * 13 / 64],
957 ),
958 14 => pack_64_14(
959 array_ref![input, 0, 1024],
960 array_mut_ref![output, 0, 1024 * 14 / 64],
961 ),
962 15 => pack_64_15(
963 array_ref![input, 0, 1024],
964 array_mut_ref![output, 0, 1024 * 15 / 64],
965 ),
966 16 => pack_64_16(
967 array_ref![input, 0, 1024],
968 array_mut_ref![output, 0, 1024 * 16 / 64],
969 ),
970 17 => pack_64_17(
971 array_ref![input, 0, 1024],
972 array_mut_ref![output, 0, 1024 * 17 / 64],
973 ),
974 18 => pack_64_18(
975 array_ref![input, 0, 1024],
976 array_mut_ref![output, 0, 1024 * 18 / 64],
977 ),
978 19 => pack_64_19(
979 array_ref![input, 0, 1024],
980 array_mut_ref![output, 0, 1024 * 19 / 64],
981 ),
982
983 20 => pack_64_20(
984 array_ref![input, 0, 1024],
985 array_mut_ref![output, 0, 1024 * 20 / 64],
986 ),
987 21 => pack_64_21(
988 array_ref![input, 0, 1024],
989 array_mut_ref![output, 0, 1024 * 21 / 64],
990 ),
991 22 => pack_64_22(
992 array_ref![input, 0, 1024],
993 array_mut_ref![output, 0, 1024 * 22 / 64],
994 ),
995 23 => pack_64_23(
996 array_ref![input, 0, 1024],
997 array_mut_ref![output, 0, 1024 * 23 / 64],
998 ),
999 24 => pack_64_24(
1000 array_ref![input, 0, 1024],
1001 array_mut_ref![output, 0, 1024 * 24 / 64],
1002 ),
1003 25 => pack_64_25(
1004 array_ref![input, 0, 1024],
1005 array_mut_ref![output, 0, 1024 * 25 / 64],
1006 ),
1007 26 => pack_64_26(
1008 array_ref![input, 0, 1024],
1009 array_mut_ref![output, 0, 1024 * 26 / 64],
1010 ),
1011 27 => pack_64_27(
1012 array_ref![input, 0, 1024],
1013 array_mut_ref![output, 0, 1024 * 27 / 64],
1014 ),
1015 28 => pack_64_28(
1016 array_ref![input, 0, 1024],
1017 array_mut_ref![output, 0, 1024 * 28 / 64],
1018 ),
1019 29 => pack_64_29(
1020 array_ref![input, 0, 1024],
1021 array_mut_ref![output, 0, 1024 * 29 / 64],
1022 ),
1023
1024 30 => pack_64_30(
1025 array_ref![input, 0, 1024],
1026 array_mut_ref![output, 0, 1024 * 30 / 64],
1027 ),
1028 31 => pack_64_31(
1029 array_ref![input, 0, 1024],
1030 array_mut_ref![output, 0, 1024 * 31 / 64],
1031 ),
1032 32 => pack_64_32(
1033 array_ref![input, 0, 1024],
1034 array_mut_ref![output, 0, 1024 * 32 / 64],
1035 ),
1036 33 => pack_64_33(
1037 array_ref![input, 0, 1024],
1038 array_mut_ref![output, 0, 1024 * 33 / 64],
1039 ),
1040 34 => pack_64_34(
1041 array_ref![input, 0, 1024],
1042 array_mut_ref![output, 0, 1024 * 34 / 64],
1043 ),
1044 35 => pack_64_35(
1045 array_ref![input, 0, 1024],
1046 array_mut_ref![output, 0, 1024 * 35 / 64],
1047 ),
1048 36 => pack_64_36(
1049 array_ref![input, 0, 1024],
1050 array_mut_ref![output, 0, 1024 * 36 / 64],
1051 ),
1052 37 => pack_64_37(
1053 array_ref![input, 0, 1024],
1054 array_mut_ref![output, 0, 1024 * 37 / 64],
1055 ),
1056 38 => pack_64_38(
1057 array_ref![input, 0, 1024],
1058 array_mut_ref![output, 0, 1024 * 38 / 64],
1059 ),
1060 39 => pack_64_39(
1061 array_ref![input, 0, 1024],
1062 array_mut_ref![output, 0, 1024 * 39 / 64],
1063 ),
1064
1065 40 => pack_64_40(
1066 array_ref![input, 0, 1024],
1067 array_mut_ref![output, 0, 1024 * 40 / 64],
1068 ),
1069 41 => pack_64_41(
1070 array_ref![input, 0, 1024],
1071 array_mut_ref![output, 0, 1024 * 41 / 64],
1072 ),
1073 42 => pack_64_42(
1074 array_ref![input, 0, 1024],
1075 array_mut_ref![output, 0, 1024 * 42 / 64],
1076 ),
1077 43 => pack_64_43(
1078 array_ref![input, 0, 1024],
1079 array_mut_ref![output, 0, 1024 * 43 / 64],
1080 ),
1081 44 => pack_64_44(
1082 array_ref![input, 0, 1024],
1083 array_mut_ref![output, 0, 1024 * 44 / 64],
1084 ),
1085 45 => pack_64_45(
1086 array_ref![input, 0, 1024],
1087 array_mut_ref![output, 0, 1024 * 45 / 64],
1088 ),
1089 46 => pack_64_46(
1090 array_ref![input, 0, 1024],
1091 array_mut_ref![output, 0, 1024 * 46 / 64],
1092 ),
1093 47 => pack_64_47(
1094 array_ref![input, 0, 1024],
1095 array_mut_ref![output, 0, 1024 * 47 / 64],
1096 ),
1097 48 => pack_64_48(
1098 array_ref![input, 0, 1024],
1099 array_mut_ref![output, 0, 1024 * 48 / 64],
1100 ),
1101 49 => pack_64_49(
1102 array_ref![input, 0, 1024],
1103 array_mut_ref![output, 0, 1024 * 49 / 64],
1104 ),
1105
1106 50 => pack_64_50(
1107 array_ref![input, 0, 1024],
1108 array_mut_ref![output, 0, 1024 * 50 / 64],
1109 ),
1110 51 => pack_64_51(
1111 array_ref![input, 0, 1024],
1112 array_mut_ref![output, 0, 1024 * 51 / 64],
1113 ),
1114 52 => pack_64_52(
1115 array_ref![input, 0, 1024],
1116 array_mut_ref![output, 0, 1024 * 52 / 64],
1117 ),
1118 53 => pack_64_53(
1119 array_ref![input, 0, 1024],
1120 array_mut_ref![output, 0, 1024 * 53 / 64],
1121 ),
1122 54 => pack_64_54(
1123 array_ref![input, 0, 1024],
1124 array_mut_ref![output, 0, 1024 * 54 / 64],
1125 ),
1126 55 => pack_64_55(
1127 array_ref![input, 0, 1024],
1128 array_mut_ref![output, 0, 1024 * 55 / 64],
1129 ),
1130 56 => pack_64_56(
1131 array_ref![input, 0, 1024],
1132 array_mut_ref![output, 0, 1024 * 56 / 64],
1133 ),
1134 57 => pack_64_57(
1135 array_ref![input, 0, 1024],
1136 array_mut_ref![output, 0, 1024 * 57 / 64],
1137 ),
1138 58 => pack_64_58(
1139 array_ref![input, 0, 1024],
1140 array_mut_ref![output, 0, 1024 * 58 / 64],
1141 ),
1142 59 => pack_64_59(
1143 array_ref![input, 0, 1024],
1144 array_mut_ref![output, 0, 1024 * 59 / 64],
1145 ),
1146
1147 60 => pack_64_60(
1148 array_ref![input, 0, 1024],
1149 array_mut_ref![output, 0, 1024 * 60 / 64],
1150 ),
1151 61 => pack_64_61(
1152 array_ref![input, 0, 1024],
1153 array_mut_ref![output, 0, 1024 * 61 / 64],
1154 ),
1155 62 => pack_64_62(
1156 array_ref![input, 0, 1024],
1157 array_mut_ref![output, 0, 1024 * 62 / 64],
1158 ),
1159 63 => pack_64_63(
1160 array_ref![input, 0, 1024],
1161 array_mut_ref![output, 0, 1024 * 63 / 64],
1162 ),
1163 64 => pack_64_64(
1164 array_ref![input, 0, 1024],
1165 array_mut_ref![output, 0, 1024 * 64 / 64],
1166 ),
1167
1168 _ => unreachable!("Unsupported width: {}", width),
1169 }
1170 }
1171
1172 unsafe fn unchecked_unpack_uninit(
1173 width: usize,
1174 input: &[Self],
1175 output: &mut [MaybeUninit<Self>],
1176 ) {
1177 let packed_len = 128 * width / size_of::<Self>();
1178 debug_assert_eq!(
1179 input.len(),
1180 packed_len,
1181 "Input buffer must be of size 1024 * W / T"
1182 );
1183 debug_assert_eq!(output.len(), 1024, "Output buffer must be of size 1024");
1184 debug_assert!(
1185 width <= Self::T,
1186 "Width must be less than or equal to {}",
1187 Self::T
1188 );
1189
1190 match width {
1191 0 => {
1192 output.fill(MaybeUninit::new(0));
1193 }
1194 1 => unpack_64_1(
1195 array_ref![input, 0, 1024 / 64],
1196 array_mut_ref![output, 0, 1024],
1197 ),
1198 2 => unpack_64_2(
1199 array_ref![input, 0, 1024 * 2 / 64],
1200 array_mut_ref![output, 0, 1024],
1201 ),
1202 3 => unpack_64_3(
1203 array_ref![input, 0, 1024 * 3 / 64],
1204 array_mut_ref![output, 0, 1024],
1205 ),
1206 4 => unpack_64_4(
1207 array_ref![input, 0, 1024 * 4 / 64],
1208 array_mut_ref![output, 0, 1024],
1209 ),
1210 5 => unpack_64_5(
1211 array_ref![input, 0, 1024 * 5 / 64],
1212 array_mut_ref![output, 0, 1024],
1213 ),
1214 6 => unpack_64_6(
1215 array_ref![input, 0, 1024 * 6 / 64],
1216 array_mut_ref![output, 0, 1024],
1217 ),
1218 7 => unpack_64_7(
1219 array_ref![input, 0, 1024 * 7 / 64],
1220 array_mut_ref![output, 0, 1024],
1221 ),
1222 8 => unpack_64_8(
1223 array_ref![input, 0, 1024 * 8 / 64],
1224 array_mut_ref![output, 0, 1024],
1225 ),
1226 9 => unpack_64_9(
1227 array_ref![input, 0, 1024 * 9 / 64],
1228 array_mut_ref![output, 0, 1024],
1229 ),
1230
1231 10 => unpack_64_10(
1232 array_ref![input, 0, 1024 * 10 / 64],
1233 array_mut_ref![output, 0, 1024],
1234 ),
1235 11 => unpack_64_11(
1236 array_ref![input, 0, 1024 * 11 / 64],
1237 array_mut_ref![output, 0, 1024],
1238 ),
1239 12 => unpack_64_12(
1240 array_ref![input, 0, 1024 * 12 / 64],
1241 array_mut_ref![output, 0, 1024],
1242 ),
1243 13 => unpack_64_13(
1244 array_ref![input, 0, 1024 * 13 / 64],
1245 array_mut_ref![output, 0, 1024],
1246 ),
1247 14 => unpack_64_14(
1248 array_ref![input, 0, 1024 * 14 / 64],
1249 array_mut_ref![output, 0, 1024],
1250 ),
1251 15 => unpack_64_15(
1252 array_ref![input, 0, 1024 * 15 / 64],
1253 array_mut_ref![output, 0, 1024],
1254 ),
1255 16 => unpack_64_16(
1256 array_ref![input, 0, 1024 * 16 / 64],
1257 array_mut_ref![output, 0, 1024],
1258 ),
1259 17 => unpack_64_17(
1260 array_ref![input, 0, 1024 * 17 / 64],
1261 array_mut_ref![output, 0, 1024],
1262 ),
1263 18 => unpack_64_18(
1264 array_ref![input, 0, 1024 * 18 / 64],
1265 array_mut_ref![output, 0, 1024],
1266 ),
1267 19 => unpack_64_19(
1268 array_ref![input, 0, 1024 * 19 / 64],
1269 array_mut_ref![output, 0, 1024],
1270 ),
1271
1272 20 => unpack_64_20(
1273 array_ref![input, 0, 1024 * 20 / 64],
1274 array_mut_ref![output, 0, 1024],
1275 ),
1276 21 => unpack_64_21(
1277 array_ref![input, 0, 1024 * 21 / 64],
1278 array_mut_ref![output, 0, 1024],
1279 ),
1280 22 => unpack_64_22(
1281 array_ref![input, 0, 1024 * 22 / 64],
1282 array_mut_ref![output, 0, 1024],
1283 ),
1284 23 => unpack_64_23(
1285 array_ref![input, 0, 1024 * 23 / 64],
1286 array_mut_ref![output, 0, 1024],
1287 ),
1288 24 => unpack_64_24(
1289 array_ref![input, 0, 1024 * 24 / 64],
1290 array_mut_ref![output, 0, 1024],
1291 ),
1292 25 => unpack_64_25(
1293 array_ref![input, 0, 1024 * 25 / 64],
1294 array_mut_ref![output, 0, 1024],
1295 ),
1296 26 => unpack_64_26(
1297 array_ref![input, 0, 1024 * 26 / 64],
1298 array_mut_ref![output, 0, 1024],
1299 ),
1300 27 => unpack_64_27(
1301 array_ref![input, 0, 1024 * 27 / 64],
1302 array_mut_ref![output, 0, 1024],
1303 ),
1304 28 => unpack_64_28(
1305 array_ref![input, 0, 1024 * 28 / 64],
1306 array_mut_ref![output, 0, 1024],
1307 ),
1308 29 => unpack_64_29(
1309 array_ref![input, 0, 1024 * 29 / 64],
1310 array_mut_ref![output, 0, 1024],
1311 ),
1312
1313 30 => unpack_64_30(
1314 array_ref![input, 0, 1024 * 30 / 64],
1315 array_mut_ref![output, 0, 1024],
1316 ),
1317 31 => unpack_64_31(
1318 array_ref![input, 0, 1024 * 31 / 64],
1319 array_mut_ref![output, 0, 1024],
1320 ),
1321 32 => unpack_64_32(
1322 array_ref![input, 0, 1024 * 32 / 64],
1323 array_mut_ref![output, 0, 1024],
1324 ),
1325 33 => unpack_64_33(
1326 array_ref![input, 0, 1024 * 33 / 64],
1327 array_mut_ref![output, 0, 1024],
1328 ),
1329 34 => unpack_64_34(
1330 array_ref![input, 0, 1024 * 34 / 64],
1331 array_mut_ref![output, 0, 1024],
1332 ),
1333 35 => unpack_64_35(
1334 array_ref![input, 0, 1024 * 35 / 64],
1335 array_mut_ref![output, 0, 1024],
1336 ),
1337 36 => unpack_64_36(
1338 array_ref![input, 0, 1024 * 36 / 64],
1339 array_mut_ref![output, 0, 1024],
1340 ),
1341 37 => unpack_64_37(
1342 array_ref![input, 0, 1024 * 37 / 64],
1343 array_mut_ref![output, 0, 1024],
1344 ),
1345 38 => unpack_64_38(
1346 array_ref![input, 0, 1024 * 38 / 64],
1347 array_mut_ref![output, 0, 1024],
1348 ),
1349 39 => unpack_64_39(
1350 array_ref![input, 0, 1024 * 39 / 64],
1351 array_mut_ref![output, 0, 1024],
1352 ),
1353
1354 40 => unpack_64_40(
1355 array_ref![input, 0, 1024 * 40 / 64],
1356 array_mut_ref![output, 0, 1024],
1357 ),
1358 41 => unpack_64_41(
1359 array_ref![input, 0, 1024 * 41 / 64],
1360 array_mut_ref![output, 0, 1024],
1361 ),
1362 42 => unpack_64_42(
1363 array_ref![input, 0, 1024 * 42 / 64],
1364 array_mut_ref![output, 0, 1024],
1365 ),
1366 43 => unpack_64_43(
1367 array_ref![input, 0, 1024 * 43 / 64],
1368 array_mut_ref![output, 0, 1024],
1369 ),
1370 44 => unpack_64_44(
1371 array_ref![input, 0, 1024 * 44 / 64],
1372 array_mut_ref![output, 0, 1024],
1373 ),
1374 45 => unpack_64_45(
1375 array_ref![input, 0, 1024 * 45 / 64],
1376 array_mut_ref![output, 0, 1024],
1377 ),
1378 46 => unpack_64_46(
1379 array_ref![input, 0, 1024 * 46 / 64],
1380 array_mut_ref![output, 0, 1024],
1381 ),
1382 47 => unpack_64_47(
1383 array_ref![input, 0, 1024 * 47 / 64],
1384 array_mut_ref![output, 0, 1024],
1385 ),
1386 48 => unpack_64_48(
1387 array_ref![input, 0, 1024 * 48 / 64],
1388 array_mut_ref![output, 0, 1024],
1389 ),
1390 49 => unpack_64_49(
1391 array_ref![input, 0, 1024 * 49 / 64],
1392 array_mut_ref![output, 0, 1024],
1393 ),
1394
1395 50 => unpack_64_50(
1396 array_ref![input, 0, 1024 * 50 / 64],
1397 array_mut_ref![output, 0, 1024],
1398 ),
1399 51 => unpack_64_51(
1400 array_ref![input, 0, 1024 * 51 / 64],
1401 array_mut_ref![output, 0, 1024],
1402 ),
1403 52 => unpack_64_52(
1404 array_ref![input, 0, 1024 * 52 / 64],
1405 array_mut_ref![output, 0, 1024],
1406 ),
1407 53 => unpack_64_53(
1408 array_ref![input, 0, 1024 * 53 / 64],
1409 array_mut_ref![output, 0, 1024],
1410 ),
1411 54 => unpack_64_54(
1412 array_ref![input, 0, 1024 * 54 / 64],
1413 array_mut_ref![output, 0, 1024],
1414 ),
1415 55 => unpack_64_55(
1416 array_ref![input, 0, 1024 * 55 / 64],
1417 array_mut_ref![output, 0, 1024],
1418 ),
1419 56 => unpack_64_56(
1420 array_ref![input, 0, 1024 * 56 / 64],
1421 array_mut_ref![output, 0, 1024],
1422 ),
1423 57 => unpack_64_57(
1424 array_ref![input, 0, 1024 * 57 / 64],
1425 array_mut_ref![output, 0, 1024],
1426 ),
1427 58 => unpack_64_58(
1428 array_ref![input, 0, 1024 * 58 / 64],
1429 array_mut_ref![output, 0, 1024],
1430 ),
1431 59 => unpack_64_59(
1432 array_ref![input, 0, 1024 * 59 / 64],
1433 array_mut_ref![output, 0, 1024],
1434 ),
1435
1436 60 => unpack_64_60(
1437 array_ref![input, 0, 1024 * 60 / 64],
1438 array_mut_ref![output, 0, 1024],
1439 ),
1440 61 => unpack_64_61(
1441 array_ref![input, 0, 1024 * 61 / 64],
1442 array_mut_ref![output, 0, 1024],
1443 ),
1444 62 => unpack_64_62(
1445 array_ref![input, 0, 1024 * 62 / 64],
1446 array_mut_ref![output, 0, 1024],
1447 ),
1448 63 => unpack_64_63(
1449 array_ref![input, 0, 1024 * 63 / 64],
1450 array_mut_ref![output, 0, 1024],
1451 ),
1452 64 => unpack_64_64(
1453 array_ref![input, 0, 1024 * 64 / 64],
1454 array_mut_ref![output, 0, 1024],
1455 ),
1456
1457 _ => unreachable!("Unsupported width: {}", width),
1458 }
1459 }
1460}
1461
1462macro_rules! unpack_8 {
1463 ($name:ident, $bits:expr) => {
1464 fn $name(input: &[u8; 1024 * $bits / u8::T], output: &mut [MaybeUninit<u8>; 1024]) {
1465 for lane in 0..u8::LANES {
1466 unpack!(u8, $bits, input, lane, |$idx, $elem| {
1467 output[$idx].write($elem);
1468 });
1469 }
1470 }
1471 };
1472}
1473
1474unpack_8!(unpack_8_1, 1);
1475unpack_8!(unpack_8_2, 2);
1476unpack_8!(unpack_8_3, 3);
1477unpack_8!(unpack_8_4, 4);
1478unpack_8!(unpack_8_5, 5);
1479unpack_8!(unpack_8_6, 6);
1480unpack_8!(unpack_8_7, 7);
1481unpack_8!(unpack_8_8, 8);
1482
1483macro_rules! pack_8 {
1484 ($name:ident, $bits:expr) => {
1485 fn $name(input: &[u8; 1024], output: &mut [MaybeUninit<u8>; 1024 * $bits / u8::T]) {
1486 for lane in 0..u8::LANES {
1487 pack!(u8, $bits, output, lane, |$idx| { input[$idx] });
1488 }
1489 }
1490 };
1491}
1492pack_8!(pack_8_1, 1);
1493pack_8!(pack_8_2, 2);
1494pack_8!(pack_8_3, 3);
1495pack_8!(pack_8_4, 4);
1496pack_8!(pack_8_5, 5);
1497pack_8!(pack_8_6, 6);
1498pack_8!(pack_8_7, 7);
1499pack_8!(pack_8_8, 8);
1500
1501macro_rules! unpack_16 {
1502 ($name:ident, $bits:expr) => {
1503 fn $name(input: &[u16; 1024 * $bits / u16::T], output: &mut [MaybeUninit<u16>; 1024]) {
1504 for lane in 0..u16::LANES {
1505 unpack!(u16, $bits, input, lane, |$idx, $elem| {
1506 output[$idx].write($elem);
1507 });
1508 }
1509 }
1510 };
1511}
1512
1513unpack_16!(unpack_16_1, 1);
1514unpack_16!(unpack_16_2, 2);
1515unpack_16!(unpack_16_3, 3);
1516unpack_16!(unpack_16_4, 4);
1517unpack_16!(unpack_16_5, 5);
1518unpack_16!(unpack_16_6, 6);
1519unpack_16!(unpack_16_7, 7);
1520unpack_16!(unpack_16_8, 8);
1521unpack_16!(unpack_16_9, 9);
1522unpack_16!(unpack_16_10, 10);
1523unpack_16!(unpack_16_11, 11);
1524unpack_16!(unpack_16_12, 12);
1525unpack_16!(unpack_16_13, 13);
1526unpack_16!(unpack_16_14, 14);
1527unpack_16!(unpack_16_15, 15);
1528unpack_16!(unpack_16_16, 16);
1529
1530macro_rules! pack_16 {
1531 ($name:ident, $bits:expr) => {
1532 fn $name(input: &[u16; 1024], output: &mut [MaybeUninit<u16>; 1024 * $bits / u16::T]) {
1533 for lane in 0..u16::LANES {
1534 pack!(u16, $bits, output, lane, |$idx| { input[$idx] });
1535 }
1536 }
1537 };
1538}
1539
1540pack_16!(pack_16_1, 1);
1541pack_16!(pack_16_2, 2);
1542pack_16!(pack_16_3, 3);
1543pack_16!(pack_16_4, 4);
1544pack_16!(pack_16_5, 5);
1545pack_16!(pack_16_6, 6);
1546pack_16!(pack_16_7, 7);
1547pack_16!(pack_16_8, 8);
1548pack_16!(pack_16_9, 9);
1549pack_16!(pack_16_10, 10);
1550pack_16!(pack_16_11, 11);
1551pack_16!(pack_16_12, 12);
1552pack_16!(pack_16_13, 13);
1553pack_16!(pack_16_14, 14);
1554pack_16!(pack_16_15, 15);
1555pack_16!(pack_16_16, 16);
1556
1557macro_rules! unpack_32 {
1558 ($name:ident, $bit_width:expr) => {
1559 fn $name(input: &[u32; 1024 * $bit_width / u32::T], output: &mut [MaybeUninit<u32>; 1024]) {
1560 for lane in 0..u32::LANES {
1561 unpack!(u32, $bit_width, input, lane, |$idx, $elem| {
1562 output[$idx].write($elem);
1563 });
1564 }
1565 }
1566 };
1567}
1568
1569unpack_32!(unpack_32_1, 1);
1570unpack_32!(unpack_32_2, 2);
1571unpack_32!(unpack_32_3, 3);
1572unpack_32!(unpack_32_4, 4);
1573unpack_32!(unpack_32_5, 5);
1574unpack_32!(unpack_32_6, 6);
1575unpack_32!(unpack_32_7, 7);
1576unpack_32!(unpack_32_8, 8);
1577unpack_32!(unpack_32_9, 9);
1578unpack_32!(unpack_32_10, 10);
1579unpack_32!(unpack_32_11, 11);
1580unpack_32!(unpack_32_12, 12);
1581unpack_32!(unpack_32_13, 13);
1582unpack_32!(unpack_32_14, 14);
1583unpack_32!(unpack_32_15, 15);
1584unpack_32!(unpack_32_16, 16);
1585unpack_32!(unpack_32_17, 17);
1586unpack_32!(unpack_32_18, 18);
1587unpack_32!(unpack_32_19, 19);
1588unpack_32!(unpack_32_20, 20);
1589unpack_32!(unpack_32_21, 21);
1590unpack_32!(unpack_32_22, 22);
1591unpack_32!(unpack_32_23, 23);
1592unpack_32!(unpack_32_24, 24);
1593unpack_32!(unpack_32_25, 25);
1594unpack_32!(unpack_32_26, 26);
1595unpack_32!(unpack_32_27, 27);
1596unpack_32!(unpack_32_28, 28);
1597unpack_32!(unpack_32_29, 29);
1598unpack_32!(unpack_32_30, 30);
1599unpack_32!(unpack_32_31, 31);
1600unpack_32!(unpack_32_32, 32);
1601
1602macro_rules! pack_32 {
1603 ($name:ident, $bits:expr) => {
1604 fn $name(
1605 input: &[u32; 1024],
1606 output: &mut [MaybeUninit<u32>; 1024 * $bits / u32::BITS as usize],
1607 ) {
1608 for lane in 0..u32::LANES {
1609 pack!(u32, $bits, output, lane, |$idx| { input[$idx] });
1610 }
1611 }
1612 };
1613}
1614
1615pack_32!(pack_32_1, 1);
1616pack_32!(pack_32_2, 2);
1617pack_32!(pack_32_3, 3);
1618pack_32!(pack_32_4, 4);
1619pack_32!(pack_32_5, 5);
1620pack_32!(pack_32_6, 6);
1621pack_32!(pack_32_7, 7);
1622pack_32!(pack_32_8, 8);
1623pack_32!(pack_32_9, 9);
1624pack_32!(pack_32_10, 10);
1625pack_32!(pack_32_11, 11);
1626pack_32!(pack_32_12, 12);
1627pack_32!(pack_32_13, 13);
1628pack_32!(pack_32_14, 14);
1629pack_32!(pack_32_15, 15);
1630pack_32!(pack_32_16, 16);
1631pack_32!(pack_32_17, 17);
1632pack_32!(pack_32_18, 18);
1633pack_32!(pack_32_19, 19);
1634pack_32!(pack_32_20, 20);
1635pack_32!(pack_32_21, 21);
1636pack_32!(pack_32_22, 22);
1637pack_32!(pack_32_23, 23);
1638pack_32!(pack_32_24, 24);
1639pack_32!(pack_32_25, 25);
1640pack_32!(pack_32_26, 26);
1641pack_32!(pack_32_27, 27);
1642pack_32!(pack_32_28, 28);
1643pack_32!(pack_32_29, 29);
1644pack_32!(pack_32_30, 30);
1645pack_32!(pack_32_31, 31);
1646pack_32!(pack_32_32, 32);
1647
1648macro_rules! unpack_64 {
1649 ($name:ident, $bit_width:expr) => {
1650 fn $name(input: &[u64; 1024 * $bit_width / u64::T], output: &mut [MaybeUninit<u64>; 1024]) {
1651 for lane in 0..u64::LANES {
1652 unpack!(u64, $bit_width, input, lane, |$idx, $elem| {
1653 output[$idx].write($elem);
1654 });
1655 }
1656 }
1657 };
1658}
1659
1660unpack_64!(unpack_64_1, 1);
1661unpack_64!(unpack_64_2, 2);
1662unpack_64!(unpack_64_3, 3);
1663unpack_64!(unpack_64_4, 4);
1664unpack_64!(unpack_64_5, 5);
1665unpack_64!(unpack_64_6, 6);
1666unpack_64!(unpack_64_7, 7);
1667unpack_64!(unpack_64_8, 8);
1668unpack_64!(unpack_64_9, 9);
1669unpack_64!(unpack_64_10, 10);
1670unpack_64!(unpack_64_11, 11);
1671unpack_64!(unpack_64_12, 12);
1672unpack_64!(unpack_64_13, 13);
1673unpack_64!(unpack_64_14, 14);
1674unpack_64!(unpack_64_15, 15);
1675unpack_64!(unpack_64_16, 16);
1676unpack_64!(unpack_64_17, 17);
1677unpack_64!(unpack_64_18, 18);
1678unpack_64!(unpack_64_19, 19);
1679unpack_64!(unpack_64_20, 20);
1680unpack_64!(unpack_64_21, 21);
1681unpack_64!(unpack_64_22, 22);
1682unpack_64!(unpack_64_23, 23);
1683unpack_64!(unpack_64_24, 24);
1684unpack_64!(unpack_64_25, 25);
1685unpack_64!(unpack_64_26, 26);
1686unpack_64!(unpack_64_27, 27);
1687unpack_64!(unpack_64_28, 28);
1688unpack_64!(unpack_64_29, 29);
1689unpack_64!(unpack_64_30, 30);
1690unpack_64!(unpack_64_31, 31);
1691unpack_64!(unpack_64_32, 32);
1692
1693unpack_64!(unpack_64_33, 33);
1694unpack_64!(unpack_64_34, 34);
1695unpack_64!(unpack_64_35, 35);
1696unpack_64!(unpack_64_36, 36);
1697unpack_64!(unpack_64_37, 37);
1698unpack_64!(unpack_64_38, 38);
1699unpack_64!(unpack_64_39, 39);
1700unpack_64!(unpack_64_40, 40);
1701unpack_64!(unpack_64_41, 41);
1702unpack_64!(unpack_64_42, 42);
1703unpack_64!(unpack_64_43, 43);
1704unpack_64!(unpack_64_44, 44);
1705unpack_64!(unpack_64_45, 45);
1706unpack_64!(unpack_64_46, 46);
1707unpack_64!(unpack_64_47, 47);
1708unpack_64!(unpack_64_48, 48);
1709unpack_64!(unpack_64_49, 49);
1710unpack_64!(unpack_64_50, 50);
1711unpack_64!(unpack_64_51, 51);
1712unpack_64!(unpack_64_52, 52);
1713unpack_64!(unpack_64_53, 53);
1714unpack_64!(unpack_64_54, 54);
1715unpack_64!(unpack_64_55, 55);
1716unpack_64!(unpack_64_56, 56);
1717unpack_64!(unpack_64_57, 57);
1718unpack_64!(unpack_64_58, 58);
1719unpack_64!(unpack_64_59, 59);
1720unpack_64!(unpack_64_60, 60);
1721unpack_64!(unpack_64_61, 61);
1722unpack_64!(unpack_64_62, 62);
1723unpack_64!(unpack_64_63, 63);
1724unpack_64!(unpack_64_64, 64);
1725
1726macro_rules! pack_64 {
1727 ($name:ident, $bits:expr) => {
1728 fn $name(
1729 input: &[u64; 1024],
1730 output: &mut [MaybeUninit<u64>; 1024 * $bits / u64::BITS as usize],
1731 ) {
1732 for lane in 0..u64::LANES {
1733 pack!(u64, $bits, output, lane, |$idx| { input[$idx] });
1734 }
1735 }
1736 };
1737}
1738
1739pack_64!(pack_64_1, 1);
1740pack_64!(pack_64_2, 2);
1741pack_64!(pack_64_3, 3);
1742pack_64!(pack_64_4, 4);
1743pack_64!(pack_64_5, 5);
1744pack_64!(pack_64_6, 6);
1745pack_64!(pack_64_7, 7);
1746pack_64!(pack_64_8, 8);
1747pack_64!(pack_64_9, 9);
1748pack_64!(pack_64_10, 10);
1749pack_64!(pack_64_11, 11);
1750pack_64!(pack_64_12, 12);
1751pack_64!(pack_64_13, 13);
1752pack_64!(pack_64_14, 14);
1753pack_64!(pack_64_15, 15);
1754pack_64!(pack_64_16, 16);
1755pack_64!(pack_64_17, 17);
1756pack_64!(pack_64_18, 18);
1757pack_64!(pack_64_19, 19);
1758pack_64!(pack_64_20, 20);
1759pack_64!(pack_64_21, 21);
1760pack_64!(pack_64_22, 22);
1761pack_64!(pack_64_23, 23);
1762pack_64!(pack_64_24, 24);
1763pack_64!(pack_64_25, 25);
1764pack_64!(pack_64_26, 26);
1765pack_64!(pack_64_27, 27);
1766pack_64!(pack_64_28, 28);
1767pack_64!(pack_64_29, 29);
1768pack_64!(pack_64_30, 30);
1769pack_64!(pack_64_31, 31);
1770pack_64!(pack_64_32, 32);
1771
1772pack_64!(pack_64_33, 33);
1773pack_64!(pack_64_34, 34);
1774pack_64!(pack_64_35, 35);
1775pack_64!(pack_64_36, 36);
1776pack_64!(pack_64_37, 37);
1777pack_64!(pack_64_38, 38);
1778pack_64!(pack_64_39, 39);
1779pack_64!(pack_64_40, 40);
1780pack_64!(pack_64_41, 41);
1781pack_64!(pack_64_42, 42);
1782pack_64!(pack_64_43, 43);
1783pack_64!(pack_64_44, 44);
1784pack_64!(pack_64_45, 45);
1785pack_64!(pack_64_46, 46);
1786pack_64!(pack_64_47, 47);
1787pack_64!(pack_64_48, 48);
1788pack_64!(pack_64_49, 49);
1789pack_64!(pack_64_50, 50);
1790pack_64!(pack_64_51, 51);
1791pack_64!(pack_64_52, 52);
1792pack_64!(pack_64_53, 53);
1793pack_64!(pack_64_54, 54);
1794pack_64!(pack_64_55, 55);
1795pack_64!(pack_64_56, 56);
1796pack_64!(pack_64_57, 57);
1797pack_64!(pack_64_58, 58);
1798pack_64!(pack_64_59, 59);
1799pack_64!(pack_64_60, 60);
1800pack_64!(pack_64_61, 61);
1801pack_64!(pack_64_62, 62);
1802pack_64!(pack_64_63, 63);
1803pack_64!(pack_64_64, 64);
1804
1805#[cfg(test)]
1806mod test {
1807 use super::*;
1808 use bitpacking::{BitPacker as ExternalBitPacker, BitPacker4x as ExternalBitPacker4x};
1809 use core::array;
1810 pub struct XorShift {
1812 state: u64,
1813 }
1814
1815 impl XorShift {
1816 pub fn new(seed: u64) -> Self {
1817 Self { state: seed }
1818 }
1819
1820 pub fn next(&mut self) -> u64 {
1821 let mut x = self.state;
1822 x ^= x << 13;
1823 x ^= x >> 7;
1824 x ^= x << 17;
1825 self.state = x;
1826 x
1827 }
1828 }
1829
1830 fn mask_for_width(width: u8) -> u32 {
1831 match width {
1832 0 => 0,
1833 32 => u32::MAX,
1834 _ => (1u32 << width) - 1,
1835 }
1836 }
1837
1838 fn raw_bitpacker4x_case(width: u8, seed: u64) -> Vec<u32> {
1839 let mask = mask_for_width(width);
1840 let mut rng = XorShift::new(seed);
1841 (0..BitPacker4x::BLOCK_LEN)
1842 .map(|idx| match seed % 4 {
1843 0 => 0,
1844 1 => mask,
1845 2 => idx as u32 & mask,
1846 _ => (rng.next() as u32) & mask,
1847 })
1848 .collect()
1849 }
1850
1851 fn sorted_bitpacker4x_case(width: u8, seed: u64) -> (u32, Vec<u32>) {
1852 if width == 0 {
1853 return (17, vec![17; BitPacker4x::BLOCK_LEN]);
1854 }
1855 if width == 32 {
1856 return (0, vec![u32::MAX; BitPacker4x::BLOCK_LEN]);
1857 }
1858
1859 let mask = mask_for_width(width).min(127);
1860 let mut rng = XorShift::new(seed);
1861 let mut current = 17u32;
1862 let values = (0..BitPacker4x::BLOCK_LEN)
1863 .map(|_| {
1864 current += (rng.next() as u32) & mask;
1865 current
1866 })
1867 .collect();
1868 (17, values)
1869 }
1870
1871 #[test]
1872 fn test_bitpacker4x_raw_compatible_with_external_bitpacking() {
1873 let ours = BitPacker4x::new();
1874 let external = ExternalBitPacker4x::new();
1875
1876 for width in 0..=32 {
1877 for seed in [0, 1, 2, 123456789] {
1878 let values = raw_bitpacker4x_case(width, seed);
1879 assert_eq!(ours.num_bits(&values), external.num_bits(&values));
1880
1881 let mut actual = vec![0u8; BitPacker4x::compressed_block_size(width)];
1882 let actual_len = ours.compress(&values, &mut actual, width);
1883
1884 let mut expected = vec![0u8; ExternalBitPacker4x::compressed_block_size(width)];
1885 let expected_len = external.compress(&values, &mut expected, width);
1886
1887 assert_eq!(actual_len, expected_len);
1888 assert_eq!(actual, expected, "width {width} seed {seed}");
1889
1890 let mut decoded = vec![0u32; BitPacker4x::BLOCK_LEN];
1891 let consumed = ours.decompress(&actual, &mut decoded, width);
1892 assert_eq!(consumed, actual_len);
1893 assert_eq!(decoded, values);
1894 }
1895 }
1896 }
1897
1898 #[test]
1899 fn test_bitpacker4x_sorted_compatible_with_external_bitpacking() {
1900 let ours = BitPacker4x::new();
1901 let external = ExternalBitPacker4x::new();
1902
1903 for width in 0..=32 {
1904 for seed in [0, 1, 2, 123456789] {
1905 let (initial, values) = sorted_bitpacker4x_case(width, seed);
1906 assert_eq!(
1907 ours.num_bits_sorted(initial, &values),
1908 external.num_bits_sorted(initial, &values)
1909 );
1910
1911 let mut actual = vec![0u8; BitPacker4x::compressed_block_size(width)];
1912 let actual_len = ours.compress_sorted(initial, &values, &mut actual, width);
1913
1914 let mut expected = vec![0u8; ExternalBitPacker4x::compressed_block_size(width)];
1915 let expected_len = external.compress_sorted(initial, &values, &mut expected, width);
1916
1917 assert_eq!(actual_len, expected_len);
1918 assert_eq!(actual, expected, "width {width} seed {seed}");
1919
1920 let mut decoded = vec![0u32; BitPacker4x::BLOCK_LEN];
1921 let consumed = ours.decompress_sorted(initial, &actual, &mut decoded, width);
1922 assert_eq!(consumed, actual_len);
1923 assert_eq!(decoded, values);
1924 }
1925 }
1926 }
1927
1928 fn pack_unpack_u8(bit_width: usize) {
1931 let mut values: [u8; 1024] = [0; 1024];
1932 let mut rng = XorShift::new(123456789);
1933 for value in &mut values {
1934 *value = (rng.next() % (1 << bit_width)) as u8;
1935 }
1936
1937 let mut packed = vec![MaybeUninit::uninit(); 1024 * bit_width / 8];
1938 for lane in 0..u8::LANES {
1939 pack!(u8, bit_width, packed, lane, |$pos| {
1941 values[$pos]
1942 });
1943 }
1944 let packed =
1946 unsafe { core::slice::from_raw_parts(packed.as_ptr().cast::<u8>(), packed.len()) };
1947
1948 let mut unpacked: [u8; 1024] = [0; 1024];
1949 for lane in 0..u8::LANES {
1950 unpack!(u8, bit_width, packed, lane, |$idx, $elem| {
1952 unpacked[$idx] = $elem;
1953 });
1954 }
1955
1956 assert_eq!(values, unpacked);
1957 }
1958
1959 fn pack_unpack_u16(bit_width: usize) {
1960 let mut values: [u16; 1024] = [0; 1024];
1961 let mut rng = XorShift::new(123456789);
1962 for value in &mut values {
1963 *value = (rng.next() % (1 << bit_width)) as u16;
1964 }
1965
1966 let mut packed = vec![MaybeUninit::uninit(); 1024 * bit_width / 16];
1967 for lane in 0..u16::LANES {
1968 pack!(u16, bit_width, packed, lane, |$pos| {
1970 values[$pos]
1971 });
1972 }
1973 let packed =
1975 unsafe { core::slice::from_raw_parts(packed.as_ptr().cast::<u16>(), packed.len()) };
1976
1977 let mut unpacked: [u16; 1024] = [0; 1024];
1978 for lane in 0..u16::LANES {
1979 unpack!(u16, bit_width, packed, lane, |$idx, $elem| {
1981 unpacked[$idx] = $elem;
1982 });
1983 }
1984
1985 assert_eq!(values, unpacked);
1986 }
1987
1988 fn pack_unpack_u32(bit_width: usize) {
1989 let mut values: [u32; 1024] = [0; 1024];
1990 let mut rng = XorShift::new(123456789);
1991 for value in &mut values {
1992 *value = (rng.next() % (1 << bit_width)) as u32;
1993 }
1994
1995 let mut packed = vec![MaybeUninit::uninit(); 1024 * bit_width / 32];
1996 for lane in 0..u32::LANES {
1997 pack!(u32, bit_width, packed, lane, |$pos| {
1999 values[$pos]
2000 });
2001 }
2002 let packed =
2004 unsafe { core::slice::from_raw_parts(packed.as_ptr().cast::<u32>(), packed.len()) };
2005
2006 let mut unpacked: [u32; 1024] = [0; 1024];
2007 for lane in 0..u32::LANES {
2008 unpack!(u32, bit_width, packed, lane, |$idx, $elem| {
2010 unpacked[$idx] = $elem;
2011 });
2012 }
2013
2014 assert_eq!(values, unpacked);
2015 }
2016
2017 fn pack_unpack_u64(bit_width: usize) {
2018 let mut values: [u64; 1024] = [0; 1024];
2019 let mut rng = XorShift::new(123456789);
2020 if bit_width == 64 {
2021 for value in &mut values {
2022 *value = rng.next();
2023 }
2024 } else {
2025 for value in &mut values {
2026 *value = rng.next() % (1 << bit_width);
2027 }
2028 }
2029
2030 let mut packed = vec![MaybeUninit::uninit(); 1024 * bit_width / 64];
2031 for lane in 0..u64::LANES {
2032 pack!(u64, bit_width, packed, lane, |$pos| {
2034 values[$pos]
2035 });
2036 }
2037 let packed =
2039 unsafe { core::slice::from_raw_parts(packed.as_ptr().cast::<u64>(), packed.len()) };
2040
2041 let mut unpacked: [u64; 1024] = [0; 1024];
2042 for lane in 0..u64::LANES {
2043 unpack!(u64, bit_width, packed, lane, |$idx, $elem| {
2045 unpacked[$idx] = $elem;
2046 });
2047 }
2048
2049 assert_eq!(values, unpacked);
2050 }
2051
2052 #[test]
2053 fn test_pack() {
2054 pack_unpack_u8(0);
2055 pack_unpack_u8(1);
2056 pack_unpack_u8(2);
2057 pack_unpack_u8(3);
2058 pack_unpack_u8(4);
2059 pack_unpack_u8(5);
2060 pack_unpack_u8(6);
2061 pack_unpack_u8(7);
2062 pack_unpack_u8(8);
2063
2064 pack_unpack_u16(0);
2065 pack_unpack_u16(1);
2066 pack_unpack_u16(2);
2067 pack_unpack_u16(3);
2068 pack_unpack_u16(4);
2069 pack_unpack_u16(5);
2070 pack_unpack_u16(6);
2071 pack_unpack_u16(7);
2072 pack_unpack_u16(8);
2073 pack_unpack_u16(9);
2074 pack_unpack_u16(10);
2075 pack_unpack_u16(11);
2076 pack_unpack_u16(12);
2077 pack_unpack_u16(13);
2078 pack_unpack_u16(14);
2079 pack_unpack_u16(15);
2080 pack_unpack_u16(16);
2081
2082 pack_unpack_u32(0);
2083 pack_unpack_u32(1);
2084 pack_unpack_u32(2);
2085 pack_unpack_u32(3);
2086 pack_unpack_u32(4);
2087 pack_unpack_u32(5);
2088 pack_unpack_u32(6);
2089 pack_unpack_u32(7);
2090 pack_unpack_u32(8);
2091 pack_unpack_u32(9);
2092 pack_unpack_u32(10);
2093 pack_unpack_u32(11);
2094 pack_unpack_u32(12);
2095 pack_unpack_u32(13);
2096 pack_unpack_u32(14);
2097 pack_unpack_u32(15);
2098 pack_unpack_u32(16);
2099 pack_unpack_u32(17);
2100 pack_unpack_u32(18);
2101 pack_unpack_u32(19);
2102 pack_unpack_u32(20);
2103 pack_unpack_u32(21);
2104 pack_unpack_u32(22);
2105 pack_unpack_u32(23);
2106 pack_unpack_u32(24);
2107 pack_unpack_u32(25);
2108 pack_unpack_u32(26);
2109 pack_unpack_u32(27);
2110 pack_unpack_u32(28);
2111 pack_unpack_u32(29);
2112 pack_unpack_u32(30);
2113 pack_unpack_u32(31);
2114 pack_unpack_u32(32);
2115
2116 pack_unpack_u64(0);
2117 pack_unpack_u64(1);
2118 pack_unpack_u64(2);
2119 pack_unpack_u64(3);
2120 pack_unpack_u64(4);
2121 pack_unpack_u64(5);
2122 pack_unpack_u64(6);
2123 pack_unpack_u64(7);
2124 pack_unpack_u64(8);
2125 pack_unpack_u64(9);
2126 pack_unpack_u64(10);
2127 pack_unpack_u64(11);
2128 pack_unpack_u64(12);
2129 pack_unpack_u64(13);
2130 pack_unpack_u64(14);
2131 pack_unpack_u64(15);
2132 pack_unpack_u64(16);
2133 pack_unpack_u64(17);
2134 pack_unpack_u64(18);
2135 pack_unpack_u64(19);
2136 pack_unpack_u64(20);
2137 pack_unpack_u64(21);
2138 pack_unpack_u64(22);
2139 pack_unpack_u64(23);
2140 pack_unpack_u64(24);
2141 pack_unpack_u64(25);
2142 pack_unpack_u64(26);
2143 pack_unpack_u64(27);
2144 pack_unpack_u64(28);
2145 pack_unpack_u64(29);
2146 pack_unpack_u64(30);
2147 pack_unpack_u64(31);
2148 pack_unpack_u64(32);
2149 pack_unpack_u64(33);
2150 pack_unpack_u64(34);
2151 pack_unpack_u64(35);
2152 pack_unpack_u64(36);
2153 pack_unpack_u64(37);
2154 pack_unpack_u64(38);
2155 pack_unpack_u64(39);
2156 pack_unpack_u64(40);
2157 pack_unpack_u64(41);
2158 pack_unpack_u64(42);
2159 pack_unpack_u64(43);
2160 pack_unpack_u64(44);
2161 pack_unpack_u64(45);
2162 pack_unpack_u64(46);
2163 pack_unpack_u64(47);
2164 pack_unpack_u64(48);
2165 pack_unpack_u64(49);
2166 pack_unpack_u64(50);
2167 pack_unpack_u64(51);
2168 pack_unpack_u64(52);
2169 pack_unpack_u64(53);
2170 pack_unpack_u64(54);
2171 pack_unpack_u64(55);
2172 pack_unpack_u64(56);
2173 pack_unpack_u64(57);
2174 pack_unpack_u64(58);
2175 pack_unpack_u64(59);
2176 pack_unpack_u64(60);
2177 pack_unpack_u64(61);
2178 pack_unpack_u64(62);
2179 pack_unpack_u64(63);
2180 pack_unpack_u64(64);
2181 }
2182
2183 fn unchecked_pack_unpack_u8(bit_width: usize) {
2184 let mut values = [0u8; 1024];
2185 let mut rng = XorShift::new(123456789);
2186 for value in &mut values {
2187 *value = (rng.next() % (1 << bit_width)) as u8;
2188 }
2189 let mut packed = vec![0; 1024 * bit_width / 8];
2190 unsafe {
2191 BitPacking::unchecked_pack(bit_width, &values, &mut packed);
2192 }
2193 let mut output = [0; 1024];
2194 unsafe { BitPacking::unchecked_unpack(bit_width, &packed, &mut output) };
2195 assert_eq!(values, output);
2196 }
2197
2198 fn unchecked_pack_unpack_u16(bit_width: usize) {
2199 let mut values = [0u16; 1024];
2200 let mut rng = XorShift::new(123456789);
2201 for value in &mut values {
2202 *value = (rng.next() % (1 << bit_width)) as u16;
2203 }
2204 let mut packed = vec![0; 1024 * bit_width / u16::T];
2205 unsafe {
2206 BitPacking::unchecked_pack(bit_width, &values, &mut packed);
2207 }
2208 let mut output = [0; 1024];
2209 unsafe { BitPacking::unchecked_unpack(bit_width, &packed, &mut output) };
2210 assert_eq!(values, output);
2211 }
2212
2213 fn unchecked_pack_unpack_u32(bit_width: usize) {
2214 let mut values = [0u32; 1024];
2215 let mut rng = XorShift::new(123456789);
2216 for value in &mut values {
2217 *value = (rng.next() % (1 << bit_width)) as u32;
2218 }
2219 let mut packed = vec![0; 1024 * bit_width / u32::T];
2220 unsafe {
2221 BitPacking::unchecked_pack(bit_width, &values, &mut packed);
2222 }
2223 let mut output = [0; 1024];
2224 unsafe { BitPacking::unchecked_unpack(bit_width, &packed, &mut output) };
2225 assert_eq!(values, output);
2226 }
2227
2228 fn unchecked_pack_unpack_u64(bit_width: usize) {
2229 let mut values = [0u64; 1024];
2230 let mut rng = XorShift::new(123456789);
2231 if bit_width == 64 {
2232 for value in &mut values {
2233 *value = rng.next();
2234 }
2235 } else {
2236 for value in &mut values {
2237 *value = rng.next() % (1 << bit_width);
2238 }
2239 }
2240 let mut packed = vec![0; 1024 * bit_width / u64::T];
2241 unsafe {
2242 BitPacking::unchecked_pack(bit_width, &values, &mut packed);
2243 }
2244 let mut output = [0; 1024];
2245 unsafe { BitPacking::unchecked_unpack(bit_width, &packed, &mut output) };
2246 assert_eq!(values, output);
2247 }
2248
2249 #[test]
2250 fn test_unchecked_pack() {
2251 let input = array::from_fn(|i| i as u32);
2252 let mut packed = [0; 320];
2253 unsafe { BitPacking::unchecked_pack(10, &input, &mut packed) };
2254 let mut output = [0; 1024];
2255 unsafe { BitPacking::unchecked_unpack(10, &packed, &mut output) };
2256 assert_eq!(input, output);
2257
2258 unchecked_pack_unpack_u8(1);
2259 unchecked_pack_unpack_u8(2);
2260 unchecked_pack_unpack_u8(3);
2261 unchecked_pack_unpack_u8(4);
2262 unchecked_pack_unpack_u8(5);
2263 unchecked_pack_unpack_u8(6);
2264 unchecked_pack_unpack_u8(7);
2265 unchecked_pack_unpack_u8(8);
2266
2267 unchecked_pack_unpack_u16(1);
2268 unchecked_pack_unpack_u16(2);
2269 unchecked_pack_unpack_u16(3);
2270 unchecked_pack_unpack_u16(4);
2271 unchecked_pack_unpack_u16(5);
2272 unchecked_pack_unpack_u16(6);
2273 unchecked_pack_unpack_u16(7);
2274 unchecked_pack_unpack_u16(8);
2275 unchecked_pack_unpack_u16(9);
2276 unchecked_pack_unpack_u16(10);
2277 unchecked_pack_unpack_u16(11);
2278 unchecked_pack_unpack_u16(12);
2279 unchecked_pack_unpack_u16(13);
2280 unchecked_pack_unpack_u16(14);
2281 unchecked_pack_unpack_u16(15);
2282 unchecked_pack_unpack_u16(16);
2283
2284 unchecked_pack_unpack_u32(1);
2285 unchecked_pack_unpack_u32(2);
2286 unchecked_pack_unpack_u32(3);
2287 unchecked_pack_unpack_u32(4);
2288 unchecked_pack_unpack_u32(5);
2289 unchecked_pack_unpack_u32(6);
2290 unchecked_pack_unpack_u32(7);
2291 unchecked_pack_unpack_u32(8);
2292 unchecked_pack_unpack_u32(9);
2293 unchecked_pack_unpack_u32(10);
2294 unchecked_pack_unpack_u32(11);
2295 unchecked_pack_unpack_u32(12);
2296 unchecked_pack_unpack_u32(13);
2297 unchecked_pack_unpack_u32(14);
2298 unchecked_pack_unpack_u32(15);
2299 unchecked_pack_unpack_u32(16);
2300 unchecked_pack_unpack_u32(17);
2301 unchecked_pack_unpack_u32(18);
2302 unchecked_pack_unpack_u32(19);
2303 unchecked_pack_unpack_u32(20);
2304 unchecked_pack_unpack_u32(21);
2305 unchecked_pack_unpack_u32(22);
2306 unchecked_pack_unpack_u32(23);
2307 unchecked_pack_unpack_u32(24);
2308 unchecked_pack_unpack_u32(25);
2309 unchecked_pack_unpack_u32(26);
2310 unchecked_pack_unpack_u32(27);
2311 unchecked_pack_unpack_u32(28);
2312 unchecked_pack_unpack_u32(29);
2313 unchecked_pack_unpack_u32(30);
2314 unchecked_pack_unpack_u32(31);
2315 unchecked_pack_unpack_u32(32);
2316
2317 unchecked_pack_unpack_u64(1);
2318 unchecked_pack_unpack_u64(2);
2319 unchecked_pack_unpack_u64(3);
2320 unchecked_pack_unpack_u64(4);
2321 unchecked_pack_unpack_u64(5);
2322 unchecked_pack_unpack_u64(6);
2323 unchecked_pack_unpack_u64(7);
2324 unchecked_pack_unpack_u64(8);
2325 unchecked_pack_unpack_u64(9);
2326 unchecked_pack_unpack_u64(10);
2327 unchecked_pack_unpack_u64(11);
2328 unchecked_pack_unpack_u64(12);
2329 unchecked_pack_unpack_u64(13);
2330 unchecked_pack_unpack_u64(14);
2331 unchecked_pack_unpack_u64(15);
2332 unchecked_pack_unpack_u64(16);
2333 unchecked_pack_unpack_u64(17);
2334 unchecked_pack_unpack_u64(18);
2335 unchecked_pack_unpack_u64(19);
2336 unchecked_pack_unpack_u64(20);
2337 unchecked_pack_unpack_u64(21);
2338 unchecked_pack_unpack_u64(22);
2339 unchecked_pack_unpack_u64(23);
2340 unchecked_pack_unpack_u64(24);
2341 unchecked_pack_unpack_u64(25);
2342 unchecked_pack_unpack_u64(26);
2343 unchecked_pack_unpack_u64(27);
2344 unchecked_pack_unpack_u64(28);
2345 unchecked_pack_unpack_u64(29);
2346 unchecked_pack_unpack_u64(30);
2347 unchecked_pack_unpack_u64(31);
2348 unchecked_pack_unpack_u64(32);
2349 unchecked_pack_unpack_u64(33);
2350 unchecked_pack_unpack_u64(34);
2351 unchecked_pack_unpack_u64(35);
2352 unchecked_pack_unpack_u64(36);
2353 unchecked_pack_unpack_u64(37);
2354 unchecked_pack_unpack_u64(38);
2355 unchecked_pack_unpack_u64(39);
2356 unchecked_pack_unpack_u64(40);
2357 unchecked_pack_unpack_u64(41);
2358 unchecked_pack_unpack_u64(42);
2359 unchecked_pack_unpack_u64(43);
2360 unchecked_pack_unpack_u64(44);
2361 unchecked_pack_unpack_u64(45);
2362 unchecked_pack_unpack_u64(46);
2363 unchecked_pack_unpack_u64(47);
2364 unchecked_pack_unpack_u64(48);
2365 unchecked_pack_unpack_u64(49);
2366 unchecked_pack_unpack_u64(50);
2367 unchecked_pack_unpack_u64(51);
2368 unchecked_pack_unpack_u64(52);
2369 unchecked_pack_unpack_u64(53);
2370 unchecked_pack_unpack_u64(54);
2371 unchecked_pack_unpack_u64(55);
2372 unchecked_pack_unpack_u64(56);
2373 unchecked_pack_unpack_u64(57);
2374 unchecked_pack_unpack_u64(58);
2375 unchecked_pack_unpack_u64(59);
2376 unchecked_pack_unpack_u64(60);
2377 unchecked_pack_unpack_u64(61);
2378 unchecked_pack_unpack_u64(62);
2379 unchecked_pack_unpack_u64(63);
2380 unchecked_pack_unpack_u64(64);
2381 }
2382}