@@ -1633,6 +1633,7 @@ def test_valid_after_initialize_only(self):
16331633 assert palettizer .lut is not None
16341634 assert torch .isfinite (palettizer .lut ).all ()
16351635 assert palettizer .quantized_lut is not None
1636+ assert not palettizer .quantized_lut .dtype .is_floating_point
16361637 scale = palettizer .lut_quantization_scale
16371638 assert scale is not None and (scale > 0 ).all ()
16381639
@@ -1681,21 +1682,20 @@ def test_repeated_reads_idempotent_with_moving_average(self):
16811682 for a , b in zip (first , second , strict = True ):
16821683 assert torch .equal (a , b )
16831684
1684- def test_lut_consistent_with_quantized_lut_and_scale (self ):
1685- """The dequantized `lut` matches `scale * quantized_lut` (int8 symmetric),
1686- confirming all four properties derive from the same frozen qparams .
1685+ def test_lut_small_quantization_error (self ):
1686+ """The dequantized `lut` reconstructs the raw centroids within one
1687+ quantization step .
16871688 """
16881689 palettizer = self ._make_palettizer (lut_qspec = _make_lut_qspec (torch .int8 ))
16891690 palettizer ._initialize (torch .randn (8 , 8 ))
16901691
1691- lut = palettizer .lut
1692- quantized_lut = palettizer .quantized_lut
1693- scale = palettizer .lut_quantization_scale
1692+ raw = palettizer ._raw_lut (palettizer .centroids )
1693+ scale = palettizer .lut_quantization_scale .max ().item ()
16941694 torch .testing .assert_close (
1695- lut .flatten (),
1696- scale . flatten () * quantized_lut . flatten (). float (),
1697- atol = 1e-4 ,
1698- rtol = 1e-4 ,
1695+ palettizer . lut .squeeze (),
1696+ raw . squeeze (),
1697+ atol = scale ,
1698+ rtol = 0 ,
16991699 )
17001700
17011701
@@ -1917,17 +1917,7 @@ def test_blocks_to_cluster_raises_on_indivisible_cluster_dim(self):
19171917 palettizer ._blocks_to_cluster (weight_2d , axis = 0 )
19181918
19191919
1920- def _accelerator_device () -> str | None :
1921- """Return an available accelerator device type ("cuda" or "mps"), else None."""
1922- if torch .cuda .is_available ():
1923- return "cuda"
1924- if torch .backends .mps .is_available ():
1925- return "mps"
1926- return None
1927-
1928-
1929- @pytest .mark .skipif (_accelerator_device () is None , reason = "requires a CUDA or MPS accelerator" )
1930- def test_device_placement_on_accelerator ():
1920+ def test_device_placement_on_accelerator (accelerator_device ):
19311921 """LUT quantization and reconstruction device behavior on an accelerator.
19321922
19331923 Checks in one pass that:
@@ -1938,7 +1928,7 @@ def test_device_placement_on_accelerator():
19381928 - ``hard_assign`` (eval) gathers against the CPU ``indices`` and returns on the
19391929 weight's device -- no accelerator/cpu device mismatch.
19401930 """
1941- device = _accelerator_device ()
1931+ device = accelerator_device
19421932
19431933 spec = PalettizationSpec (
19441934 n_bits = 2 ,
0 commit comments