Files
turboquant/tests/__pycache__/test_polar_quant.cpython-312-pytest-9.0.2.pyc

207 lines
36 KiB
Plaintext
Raw Normal View History

<EFBFBD>
<00><><EFBFBD>i3<00><00><><00>dZddlZddlmcmZddlZddl Z ejgd<03>ej<00><04>Z dejdejfd<07>Zdejdeejeffd <09>Zd
ejd ed edejfd <0A>Zdejdejdefd<0F>ZGd<10>d<11>ZGd<12>d<13>ZGd<14>d<15>ZGd<16>d<17>ZGd<18>d<19>ZGd<1A>d<1B>Zy)u<>Unit tests for PolarQuant encode/decode (#54).
Tests the core PolarQuant compression functions:
1. Encode/Decode Roundtrip: decode(encode(x)) ≈ x
2. Inner Product Preservation: Q·K ≈ Q·dequant(quant(K))
3. WHT Orthogonality: WHT^T · WHT = I
4. Codebook Correctness: Centroids match Lloyd-Max for N(0, 1/128)
5. Memory Bounds: No buffer overflows in bit packing
This is a Python reference implementation for testing. The actual
C++ implementation in llama-turbo.cpp should produce identical results.
<EFBFBD>N)g<>y<EFBFBD>):<3A>˿gt$<24><><EFBFBD>~ÿg<C3BF><67><EFBFBD><EFBFBD><E995B2>gDio<69><6F>ɴ<EFBFBD>g<EFBFBD><67>e<EFBFBD>c]<5D><>g8gDio<69><6F>g/<2F>$<06><><EFBFBD>g/<2F>$<06><>?g8gDio<69>?g<><67>e<EFBFBD>c]<5D>?gDio<69><6F>ɴ?g<><67><EFBFBD><EFBFBD>?gt$<24><><EFBFBD>~<7E>?g<>y<EFBFBD>):<3A><>?g<>Q<EFBFBD><1E><><EFBFBD>?gffffff<66>?<3F><01>dtype<70>a<>returnc<00>(<00>|j<00>}t|<00>}d}||krTtd||dz<00>D]6}t|||z<00>D]"}||}|||z}||z||<||z
|||z<<00>$<00>8|dz}||kr<01>T|dtj|<01>z z}|S)z/Fast Walsh-Hadamard Transform (in-place clone).<2E>r<00><00><00>?)<05>copy<70>len<65>range<67>np<6E>sqrt)r<00>n<>h<>i<>j<>x<>ys <20>1/private/tmp/turboquant/tests/test_polar_quant.py<70>fwhtrs<><00><00> <09><06><06><08>A<EFBFBD> <0B>A<EFBFBD><06>A<EFBFBD> <09>A<EFBFBD>
<0B>a<EFBFBD>%<25><16>q<EFBFBD>!<21>Q<EFBFBD><11>U<EFBFBD>#<23> !<21>A<EFBFBD><1A>1<EFBFBD>a<EFBFBD>!<21>e<EFBFBD>_<EFBFBD> !<21><01><15>a<EFBFBD>D<EFBFBD><01><15>a<EFBFBD>!<21>e<EFBFBD>H<EFBFBD><01><18>1<EFBFBD>u<EFBFBD><01>!<21><04><1C>q<EFBFBD>5<EFBFBD><01>!<21>a<EFBFBD>%<25><08>  !<21> !<21>
<EFBFBD>a<EFBFBD><07><01> <0C>a<EFBFBD>%<25><06><13>r<EFBFBD>w<EFBFBD>w<EFBFBD>q<EFBFBD>z<EFBFBD> <19><19>A<EFBFBD> <0C>H<EFBFBD><00>srcc<00><><00>t|<00>}t|<00>}tjj |<02>}||dzz }tj
|tj <00><02>}t|<01>D]9}tj||tz
<00>}tj|<07>||<<00>;tj
|dztj<00><02>}td|d<03>D]}||||dzdzz||dz<<00>||fS)uPolarQuant encode (4-bit quantization).
Returns:
(packed_bytes, norm) — packed is uint8 array of length d/2
<20><><EFBFBD>&<26> .>rr rr<00>) r rr<00>linalg<6C>norm<72>zeros<6F>int32r <00>abs<62>TURBO4_CENTROIDS<44>argmin<69>uint8) r<00>d<>rotatedr<00>
normalized<EFBFBD>indicesr<00> distances<65>packeds r<00>polar_quant_encoder+1s<><00><00> <0C>C<EFBFBD><08>A<EFBFBD><13>3<EFBFBD>i<EFBFBD>G<EFBFBD> <0E>9<EFBFBD>9<EFBFBD>><3E>><3E>'<27> "<22>D<EFBFBD><19>D<EFBFBD>4<EFBFBD>K<EFBFBD>(<28>J<EFBFBD><11>h<EFBFBD>h<EFBFBD>q<EFBFBD><02><08><08>)<29>G<EFBFBD> <12>1<EFBFBD>X<EFBFBD>*<2A><01><16>F<EFBFBD>F<EFBFBD>:<3A>a<EFBFBD>=<3D>+;<3B>;<3B><<3C> <09><17>Y<EFBFBD>Y<EFBFBD>y<EFBFBD>)<29><07><01>
<EFBFBD>*<2A>
<10>X<EFBFBD>X<EFBFBD>a<EFBFBD>1<EFBFBD>f<EFBFBD>B<EFBFBD>H<EFBFBD>H<EFBFBD> -<2D>F<EFBFBD> <12>1<EFBFBD>a<EFBFBD><11>^<5E><<3C><01> <20><11><1A>w<EFBFBD>q<EFBFBD>1<EFBFBD>u<EFBFBD>~<7E><11>':<3A>;<3B><06>q<EFBFBD>A<EFBFBD>v<EFBFBD><0E><<3C> <12>4<EFBFBD><<3C>rr*rr%c<00><><00>tj|tj<00><01>}t|<02>D]'}|dzdk(r||dzdz||<<00>||dzdz ||<<00>)t||z}t |<05>}|S)z<>PolarQuant decode (4-bit dequantization).
Args:
packed: uint8 array of length d/2
norm: L2 norm from encode
d: original dimension
Returns:
Reconstructed float array of length d
rr r<00>r)rrr r r"r)r*rr%r(r<00>dsts r<00>polar_quant_decoder/Ps<><00><00><11>h<EFBFBD>h<EFBFBD>q<EFBFBD><02><08><08>)<29>G<EFBFBD> <12>1<EFBFBD>X<EFBFBD>-<2D><01> <0C>q<EFBFBD>5<EFBFBD>A<EFBFBD>:<3A><1F><01>Q<EFBFBD><06><1E>$<24>.<2E>G<EFBFBD>A<EFBFBD>J<EFBFBD><1F><01>Q<EFBFBD><06><1E>1<EFBFBD>,<2C>G<EFBFBD>A<EFBFBD>J<EFBFBD> -<2D> <1B>7<EFBFBD>
#<23>d<EFBFBD>
*<2A>C<EFBFBD> <0F>s<EFBFBD>)<29>C<EFBFBD> <0E>Jr<00>bc<00>@<00>ttj||<01><00>S)zCompute inner product.)<03>floatr<00>dot)rr0s r<00> inner_productr4ls<00><00> <10><12><16><16><01>1<EFBFBD><1C> <1E>rc<00>4<00>eZdZdZd<02>Zd<03>Zd<04>Zd<05>Zd<06>Zd<07>Z y) <09>TestEncodeDecodeRoundtripudecode(encode(x)) ≈ xc<00><><00>tjjd<01>tjjd<02>j tj
<00>}t |<01>\}}t||d<02>}tjtj||z
<00><00>}d}||k}|s<>tjd|fd||f<02>dtj<00>vstj|<05>rtj|<05>ndtj|<06>d<07>z}tj d|<05><00><02>d zd
|iz} t#tj$| <09><00><00>dx}}y) N<>*<00>@r
<00><01><<3C>z%(py0)s < %(py3)s<>error<6F><02>py0<79>py3<79>Roundtrip error too large: <20>
>assert %(py5)s<>py5<79>r<00>random<6F>seed<65>randn<64>astype<70>float32r+r/<00>maxr!<00>
@pytest_ar<61>_call_reprcompare<72> @py_builtins<6E>locals<6C>_should_repr_global_name<6D> _saferepr<70>_format_assertmsg<73>AssertionError<6F>_format_explanation<6F>
<EFBFBD>selfrr*r<00> recoveredr=<00> @py_assert2<74> @py_assert1<74> @py_format4<74> @py_format6s
r<00>test_roundtrip_d64z,TestEncodeDecodeRoundtrip.test_roundtrip_d64xs<><00><00>
<EFBFBD> <09> <09><0E><0E>r<EFBFBD><1A> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>B<EFBFBD> <1F> &<26> &<26>r<EFBFBD>z<EFBFBD>z<EFBFBD> 2<><01>)<29>!<21>,<2C> <0C><06><04>&<26>v<EFBFBD>t<EFBFBD>R<EFBFBD>8<> <09><13><06><06>r<EFBFBD>v<EFBFBD>v<EFBFBD>a<EFBFBD>)<29>m<EFBFBD>,<2C>-<2D><05><1A>A<>u<EFBFBD>s<EFBFBD>{<7B>A<>A<>A<>u<EFBFBD>s<EFBFBD>A<>A<>A<>A<>A<>A<>u<EFBFBD>A<>A<>A<>u<EFBFBD>A<>A<>A<>s<EFBFBD>A<>A<>A<>9<>%<25><17>A<>A<>A<>A<>A<>A<>Arc<00><><00>tjjd<01>tjjd<02>j tj
<00>}t |<01>\}}t||d<02>}tjtj||z
<00><00>}d}||k}|s<>tjd|fd||f<02>dtj<00>vstj|<05>rtj|<05>ndtj|<06>d<07>z}tj d|<05><00><02>d zd
|iz} t#tj$| <09><00><00>dx}}y) Nr8<00><>g<00>?r:r<r=r>rArBrCrDrTs
r<00>test_roundtrip_d128z-TestEncodeDecodeRoundtrip.test_roundtrip_d128<32><00><><00><00>
<EFBFBD> <09> <09><0E><0E>r<EFBFBD><1A> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01>)<29>!<21>,<2C> <0C><06><04>&<26>v<EFBFBD>t<EFBFBD>S<EFBFBD>9<> <09><12><06><06>r<EFBFBD>v<EFBFBD>v<EFBFBD>a<EFBFBD>)<29>m<EFBFBD>,<2C>-<2D><05><1A>A<>u<EFBFBD>s<EFBFBD>{<7B>A<>A<>A<>u<EFBFBD>s<EFBFBD>A<>A<>A<>A<>A<>A<>u<EFBFBD>A<>A<>A<>u<EFBFBD>A<>A<>A<>s<EFBFBD>A<>A<>A<>9<>%<25><17>A<>A<>A<>A<>A<>A<>Arc<00><><00>tjjd<01>tjjd<02>j tj
<00>}t |<01>\}}t||d<02>}tjtj||z
<00><00>}d}||k}|s<>tjd|fd||f<02>dtj<00>vstj|<05>rtj|<05>ndtj|<06>d<07>z}tj d|<05><00><02>d zd
|iz} t#tj$| <09><00><00>dx}}y) Nr8<00>g@r:r<r=r>rArBrCrDrTs
r<00>test_roundtrip_d256z-TestEncodeDecodeRoundtrip.test_roundtrip_d256<35>r_rc <00><00>tjdtj<00><02>}t|<01>\}}t ||d<01>}tj
}tj }||<04>}||<07>}d} || k}
|
<EFBFBD>s{tjd|
fd|| f<02>dtj<00>vstjt<00>rtjt<00>ndtj|<05>dtj<00>vstjt<00>rtjt<00>ndtj|<06>dtj<00>vstj|<04>rtj|<04>ndtj|<07>tj|<08>tj| <09>d<08>z} d d
| iz} ttj| <0C><00><00>dx}x}x}x}x}
} y) Nr]rg{<14>G<EFBFBD>z<EFBFBD>?r:)z<>%(py10)s
{%(py10)s = %(py2)s
{%(py2)s = %(py0)s.max
}(%(py8)s
{%(py8)s = %(py5)s
{%(py5)s = %(py3)s.abs
}(%(py6)s)
})
} < %(py13)srrV)r?<00>py2r@rC<00>py6<79>py8<79>py10<31>py13<31>assert %(py15)s<>py15<31>rrrIr+r/rJr!rKrLrMrNrOrPrRrS) rUrr*rrVrX<00> @py_assert4<74> @py_assert7<74> @py_assert9<74> @py_assert12<31> @py_assert11<31> @py_format14<31> @py_format16s r<00>test_roundtrip_zero_vectorz4TestEncodeDecodeRoundtrip.test_roundtrip_zero_vector<6F>s%<00><00> <0E>H<EFBFBD>H<EFBFBD>S<EFBFBD><02>
<EFBFBD>
<EFBFBD> +<2B><01>)<29>!<21>,<2C> <0C><06><04>&<26>v<EFBFBD>t<EFBFBD>S<EFBFBD>9<> <09><12>v<EFBFBD>v<EFBFBD>/<2F>b<EFBFBD>f<EFBFBD>f<EFBFBD>/<2F>f<EFBFBD>Y<EFBFBD>'<27>/<2F>v<EFBFBD>'<27>(<28>/<2F>4<EFBFBD>/<2F>(<28>4<EFBFBD>/<2F>/<2F>/<2F>/<2F>(<28>4<EFBFBD>/<2F>/<2F>/<2F>/<2F>/<2F>/<2F>r<EFBFBD>/<2F>/<2F>/<2F>r<EFBFBD>/<2F>/<2F>/<2F>v<EFBFBD>/<2F>/<2F>/<2F>/<2F>/<2F>/<2F>b<EFBFBD>/<2F>/<2F>/<2F>b<EFBFBD>/<2F>/<2F>/<2F>f<EFBFBD>/<2F>/<2F>/<2F>/<2F>/<2F>/<2F>Y<EFBFBD>/<2F>/<2F>/<2F>Y<EFBFBD>/<2F>/<2F>/<2F>'<27>/<2F>/<2F>/<2F>(<28>/<2F>/<2F>/<2F>4<EFBFBD>/<2F>/<2F>/<2F>/<2F>/<2F>/<2F>/<2F>/rc<00>0<00>tjdtj<00><02>}d|d<t|<01>\}}t ||d<01>}tj
tj ||z
<00><00>}d}||k}|s<>tjd|fd||f<02>dtj<00>vstj|<05>rtj|<05>ndtj|<06>d<08>z}d d
|iz} ttj| <09><00><00>dx}}y) Nr]rr
rr:r<r=r><00>assert %(py5)srCrkrTs
r<00>test_roundtrip_unit_vectorz4TestEncodeDecodeRoundtrip.test_roundtrip_unit_vector<6F>s<><00><00> <0E>H<EFBFBD>H<EFBFBD>S<EFBFBD><02>
<EFBFBD>
<EFBFBD> +<2B><01><12><01>!<21><04>)<29>!<21>,<2C> <0C><06><04>&<26>v<EFBFBD>t<EFBFBD>S<EFBFBD>9<> <09><12><06><06>r<EFBFBD>v<EFBFBD>v<EFBFBD>a<EFBFBD>)<29>m<EFBFBD>,<2C>-<2D><05><1A><1A>u<EFBFBD>s<EFBFBD>{<7B><1A><1A><1A>u<EFBFBD>s<EFBFBD><1A><1A><1A><1A><1A><1A>u<EFBFBD><1A><1A><1A>u<EFBFBD><1A><1A><1A>s<EFBFBD><1A><1A><1A><1A><1A><1A>rc<00><><00>tjgd<01>dztj<00><03>}t|<01>\}}t ||d<04>}tj
j |<01>}tj
j |<04>}t||z
<00>|z }d}||k} | s<>tjd| fd||f<02>dtj<00>vstj|<07>rtj|<07>ndtj|<08>d <09>z}
tjd
|d <0B><04><02>d zd |
iz} ttj | <0B><00><00>dx} }y)z3Large values should recover with similar magnitude.)g$@g$<24>g@g<14><> rr]<00><00>?r:r<<00> rel_errorr>zMagnitude not preserved: <20>.3frBrCN)r<00>arrayrIr+r/rrr!rKrLrMrNrOrPrQrRrS) rUrr*rrV<00> norm_orig<69>norm_recrzrWrXrYrZs r<00>"test_roundtrip_magnitude_preservedz<TestEncodeDecodeRoundtrip.test_roundtrip_magnitude_preserved<65>s<><00><00> <0E>H<EFBFBD>H<EFBFBD>-<2D><02>2<>"<22>*<2A>*<2A> E<><01>)<29>!<21>,<2C> <0C><06><04>&<26>v<EFBFBD>t<EFBFBD>S<EFBFBD>9<> <09><17>I<EFBFBD>I<EFBFBD>N<EFBFBD>N<EFBFBD>1<EFBFBD>%<25> <09><15>9<EFBFBD>9<EFBFBD>><3E>><3E>)<29>,<2C><08><17> <09>H<EFBFBD>,<2C>-<2D> <09>9<> <09><1E>K<>y<EFBFBD>3<EFBFBD><EFBFBD>K<>K<>K<>y<EFBFBD>3<EFBFBD>K<>K<>K<>K<>K<>K<>y<EFBFBD>K<>K<>K<>y<EFBFBD>K<>K<>K<>3<EFBFBD>K<>K<>K<>";<3B>I<EFBFBD>c<EFBFBD>?<3F> K<>K<>K<>K<>K<>K<>KrN)
<EFBFBD>__name__<5F>
__module__<EFBFBD> __qualname__<5F>__doc__r[r^rbrsrvr<00>rrr6r6us'<00><00>!<21>B<01>B<01>B<01>0<><1B>
Lrr6c<00><00>eZdZdZd<02>Zd<03>Zy)<05>TestInnerProductPreservationuQ·K ≈ Q·dequant(quant(K))c<00>R<00>tjjd<01>tjjd<02>j tj
<00>}tjjd<02>j tj
<00>}t ||<02>}t|<02>\}}t||d<02>}t ||<06>}t||z
<00>t|<03>dzz }d} || k}
|
s<EFBFBD>tjd|
fd|| f<02>dtj<00>vstj|<08>rtj|<08>ndtj| <09>d<08>z} tj d |d
<EFBFBD><04><02>d zd | iz} t#tj$| <0C><00><00>dx}
} y) Nr8r]rryr:r<rzr>zInner product error too large: r{rBrC)rrErFrGrHrIr4r+r/r!rKrLrMrNrOrPrQrRrS) rU<00>q<>k<> ip_originalr*r<00> k_recovered<65> ip_compressedrzrWrXrYrZs r<00>test_inner_product_preservedz9TestInnerProductPreservation.test_inner_product_preserved<65>s<00><00>
<EFBFBD> <09> <09><0E><0E>r<EFBFBD><1A> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01>$<24>A<EFBFBD>q<EFBFBD>)<29> <0B>*<2A>!<21>,<2C> <0C><06><04>(<28><16><14>s<EFBFBD>;<3B> <0B>%<25>a<EFBFBD><1B>5<> <0A><18> <0B>m<EFBFBD>3<>4<><03>K<EFBFBD>8H<38>4<EFBFBD>8O<38>P<> <09><1E>Q<>y<EFBFBD>3<EFBFBD><EFBFBD>Q<>Q<>Q<>y<EFBFBD>3<EFBFBD>Q<>Q<>Q<>Q<>Q<>Q<>y<EFBFBD>Q<>Q<>Q<>y<EFBFBD>Q<>Q<>Q<>3<EFBFBD>Q<>Q<>Q<>"A<>)<29>C<EFBFBD><1F> Q<>Q<>Q<>Q<>Q<>Q<>Qrc <00><><00>tjjd<01>tjjd<02>j tj
<00>}|dz}t ||<02>}t|<02>\}}t||d<02>}t ||<06>}d}||kD} | s<>tjd| fd||f<02>dtj<00>vstj|<03>rtj|<03>ndtj|<08>d<08>z}
d d
|
iz} ttj | <0B><00><00>d x} }d}||kD} | s<>tjd| fd||f<02>d tj<00>vstj|<07>rtj|<07>nd tj|<08>d<08>z}
d d
|
iz} ttj | <0B><00><00>d x} }||z
} t#| <0C>} t#|<03>}| |z }d }||k}|<11>s<>tjd|fd||f<02>dtj<00>vstjt"<00>rtjt"<00>nddtj<00>vstj|<03>rtj|<03>ndd tj<00>vstj|<07>rtj|<07>nd tj| <0A>dtj<00>vstjt"<00>rtjt"<00>nddtj<00>vstj|<03>rtj|<03>ndtj|<0E>tj|<10>d<11>z}dd|iz}ttj |<13><00><00>d x} x} x}x}x}}y )z9Vectors in same direction should have high inner product.r8r]g<><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?r<00><01>><3E>z%(py0)s > %(py3)sr<73>r>rurCNr<4E><00>333333<33>?r:)zf(%(py5)s
{%(py5)s = %(py0)s((%(py1)s - %(py2)s))
} / %(py9)s
{%(py9)s = %(py6)s(%(py7)s)
}) < %(py13)sr!)r?<00>py1rdrCre<00>py7<79>py9rhrirj)rrErFrGrHrIr4r+r/rKrLrMrNrOrPrRrSr!)rUr<>r<>r<>r*rr<>r<>rWrXrYrZ<00> @py_assert3rl<00> @py_assert8<74> @py_assert10rorprqrrs r<00>!test_inner_product_same_directionz>TestInnerProductPreservation.test_inner_product_same_direction<6F>s@<00><00>
<EFBFBD> <09> <09><0E><0E>r<EFBFBD><1A> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01> <0A><03>G<EFBFBD><01>#<23>A<EFBFBD>q<EFBFBD>)<29> <0B>)<29>!<21>,<2C> <0C><06><04>(<28><16><14>s<EFBFBD>;<3B> <0B>%<25>a<EFBFBD><1B>5<> <0A><1F><1E>{<7B>Q<EFBFBD><EFBFBD><1E><1E><1E>{<7B>Q<EFBFBD><1E><1E><1E><1E><1E><1E>{<7B><1E><1E><1E>{<7B><1E><1E><1E>Q<EFBFBD><1E><1E><1E><1E><1E><1E><1E> <20> <20>}<7D>q<EFBFBD> <20> <20> <20> <20>}<7D>q<EFBFBD> <20> <20> <20> <20> <20> <20>}<7D> <20> <20> <20>}<7D> <20> <20> <20>q<EFBFBD> <20> <20> <20> <20> <20> <20> <20><1E><1D>.<2E>H<>s<EFBFBD>.<2E>/<2F>H<>#<23>k<EFBFBD>2B<32>H<>/<2F>2B<32>B<>H<>S<EFBFBD>H<>B<>S<EFBFBD>H<>H<>H<>H<>B<>S<EFBFBD>H<>H<>H<>H<>H<>H<>s<EFBFBD>H<>H<>H<>s<EFBFBD>H<>H<>H<>H<>H<>H<>;<3B>H<>H<>H<>;<3B>H<>H<>H<>H<>H<>H<><1D>H<>H<>H<><1D>H<>H<>H<>/<2F>H<>H<>H<>H<>H<>H<>#<23>H<>H<>H<>#<23>H<>H<>H<>H<>H<>H<>k<EFBFBD>H<>H<>H<>k<EFBFBD>H<>H<>H<>2B<32>H<>H<>H<>S<EFBFBD>H<>H<>H<>H<>H<>H<>H<>HrN)r<>r<>r<>r<>r<>r<>r<>rrr<>r<><00>s<00><00>'<27>R<01>"Irr<>c<00>"<00>eZdZdZd<02>Zd<03>Zd<04>Zy)<06>TestWHTOrthogonalityuWHT^T · WHT = Ic<00>*<00>d}tj||ftj<00><02>}t|<01>D]>}tj|tj<00><02>}d||<t |<04>|dd<00>|f<<00>@|j
|z}tj |tj<00><02>}tjtj||z
<00><00>}d}||k} | s<>tjd| fd||f<02>dtj<00>vstj|<07>rtj|<07>ndtj|<08>d<08>z}
tjd |<07><00><02>d
zd |
iz} t!tj"| <0B><00><00>dx} }y) Nr9rr
<00><>h㈵<68><E388B5>>r:r<r=r><00>WHT not orthogonal: max error rBrC<00>rrrIr r<00>T<>eyerJr!rKrLrMrNrOrPrQrRrS<00> rUr<00>Wr<00>col<6F>product<63>identityr=rWrXrYrZs r<00>test_wht_orthogonal_d64z,TestWHTOrthogonality.test_wht_orthogonal_d64<36>s<00><00> <0E><01> <0E>H<EFBFBD>H<EFBFBD>a<EFBFBD><11>V<EFBFBD>2<EFBFBD>:<3A>:<3A> .<2E><01><16>q<EFBFBD><18> <20>A<EFBFBD><14>(<28>(<28>1<EFBFBD>B<EFBFBD>J<EFBFBD>J<EFBFBD>/<2F>C<EFBFBD><18>C<EFBFBD><01>F<EFBFBD><1A>3<EFBFBD>i<EFBFBD>A<EFBFBD>a<EFBFBD><11>d<EFBFBD>G<EFBFBD> <20> <14>#<23>#<23><01>'<27><07><15>6<EFBFBD>6<EFBFBD>!<21>2<EFBFBD>:<3A>:<3A>.<2E><08><12><06><06>r<EFBFBD>v<EFBFBD>v<EFBFBD>g<EFBFBD><08>0<>1<>2<><05><1B>E<>u<EFBFBD>t<EFBFBD>|<7C>E<>E<>E<>u<EFBFBD>t<EFBFBD>E<>E<>E<>E<>E<>E<>u<EFBFBD>E<>E<>E<>u<EFBFBD>E<>E<>E<>t<EFBFBD>E<>E<>E<>=<3D>e<EFBFBD>W<EFBFBD>E<>E<>E<>E<>E<>E<>Erc<00>*<00>d}tj||ftj<00><02>}t|<01>D]>}tj|tj<00><02>}d||<t |<04>|dd<00>|f<<00>@|j
|z}tj |tj<00><02>}tjtj||z
<00><00>}d}||k} | s<>tjd| fd||f<02>dtj<00>vstj|<07>rtj|<07>ndtj|<08>d<08>z}
tjd |<07><00><02>d
zd |
iz} t!tj"| <0B><00><00>dx} }y) Nr]rr
r<>r:r<r=r>r<>rBrCr<>r<>s r<00>test_wht_orthogonal_d128z-TestWHTOrthogonality.test_wht_orthogonal_d128<32>s<00><00> <0F><01> <0E>H<EFBFBD>H<EFBFBD>a<EFBFBD><11>V<EFBFBD>2<EFBFBD>:<3A>:<3A> .<2E><01><16>q<EFBFBD><18> <20>A<EFBFBD><14>(<28>(<28>1<EFBFBD>B<EFBFBD>J<EFBFBD>J<EFBFBD>/<2F>C<EFBFBD><18>C<EFBFBD><01>F<EFBFBD><1A>3<EFBFBD>i<EFBFBD>A<EFBFBD>a<EFBFBD><11>d<EFBFBD>G<EFBFBD> <20>
<14>#<23>#<23><01>'<27><07><15>6<EFBFBD>6<EFBFBD>!<21>2<EFBFBD>:<3A>:<3A>.<2E><08><12><06><06>r<EFBFBD>v<EFBFBD>v<EFBFBD>g<EFBFBD><08>0<>1<>2<><05><1B>E<>u<EFBFBD>t<EFBFBD>|<7C>E<>E<>E<>u<EFBFBD>t<EFBFBD>E<>E<>E<>E<>E<>E<>u<EFBFBD>E<>E<>E<>u<EFBFBD>E<>E<>E<>t<EFBFBD>E<>E<>E<>=<3D>e<EFBFBD>W<EFBFBD>E<>E<>E<>E<>E<>E<>Erc<00><><00>tjjd<01>tjjd<02>j tj
<00>}tj |dz<00>}t|<01>}tj |dz<00>}t||z
<00>|z }d}||k}|s<>tjd|fd||f<02>dtj<00>vstj|<05>rtj|<05>ndtj|<06>d<08>z}tjd |<05><00><02>d
zd |iz} t!tj"| <09><00><00>d x}}y ) z)||WHT(x)|| = ||x|| (energy preservation).r8r]r r<>r:r<rzr>zEnergy not preserved: rBrCN)rrErFrGrHrI<00>sumrr!rKrLrMrNrOrPrQrRrS)
rUr<00> energy_beforer<00> energy_afterrzrWrXrYrZs
r<00>test_wht_preserves_energyz.TestWHTOrthogonality.test_wht_preserves_energy<67>s<><00><00>
<EFBFBD> <09> <09><0E><0E>r<EFBFBD><1A> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01><1A><06><06>q<EFBFBD>A<EFBFBD>v<EFBFBD><0E> <0A> <10><11>G<EFBFBD><01><19>v<EFBFBD>v<EFBFBD>a<EFBFBD>1<EFBFBD>f<EFBFBD>~<7E> <0C><17> <0A> <0C>4<>5<> <0A>E<> <09><1F>E<>y<EFBFBD>4<EFBFBD><1F>E<>E<>E<>y<EFBFBD>4<EFBFBD>E<>E<>E<>E<>E<>E<>y<EFBFBD>E<>E<>E<>y<EFBFBD>E<>E<>E<>4<EFBFBD>E<>E<>E<>#9<>)<29><1B>!E<>E<>E<>E<>E<>E<>ErN)r<>r<>r<>r<>r<>r<>r<>r<>rrr<>r<><00>s<00><00><1A> F<01> F<01>
Frr<>c<00>(<00>eZdZdZd<02>Zd<03>Zd<04>Zd<05>Zy)<07>TestCodebookCorrectnessz)Centroids match Lloyd-Max for N(0, 1/128)c<00>R<00>tjtdkD<00>}tjtdk<00>}||z
}t|<03>}d}||k}|<06>sMt j
d|fd||f<02>dt j<00>vst jt<00>rt jt<00>nddt j<00>vst j|<01>rt j|<01>nddt j<00>vst j|<02>rt j|<02>ndt j|<04>t j|<05>d<08>z}t jd <09>d
zd |iz}tt j|<08><00><00>d x}x}x}}y ) z8Centroids should be approximately symmetric around zero.rr )<01><=)z<%(py5)s
{%(py5)s = %(py0)s((%(py1)s - %(py2)s))
} <= %(py8)sr!<00> pos_count<6E> neg_count)r?r<>rdrCrfzCentroids not balancedz
>assert %(py10)srgN) rr<>r"r!rKrLrMrNrOrPrQrRrS) rUr<>r<>r<>rlrm<00> @py_assert6<74> @py_format9<74> @py_format11s r<00>test_centroids_symmetricz0TestCodebookCorrectness.test_centroids_symmetrics<><00><00><17>F<EFBFBD>F<EFBFBD>+<2B>a<EFBFBD>/<2F>0<> <09><16>F<EFBFBD>F<EFBFBD>+<2B>a<EFBFBD>/<2F>0<> <09><1C>y<EFBFBD>(<28>H<>s<EFBFBD>(<28>)<29>H<>Q<EFBFBD>H<>)<29>Q<EFBFBD>.<2E>H<>H<>H<>)<29>Q<EFBFBD>H<>H<>H<>H<>H<>H<>s<EFBFBD>H<>H<>H<>s<EFBFBD>H<>H<>H<>H<>H<>H<>9<EFBFBD>H<>H<>H<>9<EFBFBD>H<>H<>H<>H<>H<>H<>y<EFBFBD>H<>H<>H<>y<EFBFBD>H<>H<>H<>)<29>H<>H<>H<>Q<EFBFBD>H<>H<>H<>0H<30>H<>H<>H<>H<>H<>H<>Hrc<00>r<00>td<01>D]<5D>}t|}t|dz}||k}|s<>tjd|fd||f<02>tj|<02>tj|<03>d<05>z}tj
d|<01><00><02>dzd|iz}t tj|<06><00><00>d x}x}}<03><>y )
z'Centroids should be in ascending order.r-rr:)z%(py1)s < %(py4)s<>r<><00>py4zCentroids not ordered at z
>assert %(py6)sreN)r r"rKrLrPrQrRrS)rUr<00> @py_assert0r<30>rW<00> @py_format5<74> @py_format7s r<00>test_centroids_orderedz.TestCodebookCorrectness.test_centroids_ordereds<><00><00><16>r<EFBFBD><19> 0<>A<EFBFBD>#<23>A<EFBFBD>&<26> 0<>)9<>!<21>a<EFBFBD>%<25>)@<40> 0<>&<26>)@<40>@<40> 0<>/<2F>/<2F> 0<>&<26>)@<40> 0<> 0<>&/<2F>i<EFBFBD>'<27> 0<> 0<>&/<2F>i<EFBFBD>*A<01> 0<> 0<>/<2F>/<2F>+<2B>A<EFBFBD>3<EFBFBD>/<2F> 0<> 0<> 0<>/<2F>/<2F> 0<> 0<> 0<> 0rc<00><00>td}d}| }||k}|sltjd|fd||f<02>tj|<01>tj|<02>d<05>z}dd|iz}t tj
|<06><00><00>dx}x}x}}td }d
}||kD}|sltjd |fd ||f<02>tj|<01>tj|<02>d<05>z}d d|iz}t tj
|<08><00><00>dx}x}}y)z/Centroids should cover the range [-0.35, 0.35].rg<><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?r:)z%(py1)s < -%(py4)sr<73>zassert %(py7)sr<73>N<><4E><EFBFBD><EFBFBD><EFBFBD>r<EFBFBD>r<>)z%(py1)s > %(py4)szassert %(py6)sre)r"rKrLrPrRrS) rUr<>r<><00> @py_assert5rWrZ<00> @py_format8r<38>r<>s r<00>test_centroids_coveragez/TestCodebookCorrectness.test_centroids_coverage s<><00><00><1F><01>"<22>)<29>c<EFBFBD>)<29>c<EFBFBD>T<EFBFBD>)<29>"<22>T<EFBFBD>)<29>)<29>)<29>)<29>"<22>T<EFBFBD>)<29>)<29>)<29>"<22>)<29>)<29>)<29>c<EFBFBD>)<29>)<29>)<29>)<29>)<29>)<29>)<29><1F><02>#<23>)<29>c<EFBFBD>)<29>#<23>c<EFBFBD>)<29>)<29>)<29>)<29>#<23>c<EFBFBD>)<29>)<29>)<29>#<23>)<29>)<29>)<29>c<EFBFBD>)<29>)<29>)<29>)<29>)<29>)<29>)rc<00><<00>tt<00>}d}||k(}|s<>tjd|fd||f<02>dt j
<00>vstj t<00>rtjt<00>nddt j
<00>vstj t<00>rtjt<00>ndtj|<01>tj|<02>d<06>z}dd|iz}ttj|<05><00><00>d x}x}}y )
z8Should have exactly 16 centroids for 4-bit quantization.<2E><00><01>==<3D>z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr r"<00>r?r<>r@rezassert %(py8)srfN)
r r"rKrLrMrNrOrPrRrS)rUrWr<>rlr<>r<>s r<00>test_centroids_16_levelsz0TestCodebookCorrectness.test_centroids_16_levels%s<><00><00><12>#<23>$<24>*<2A><02>*<2A>$<24><02>*<2A>*<2A>*<2A>*<2A>$<24><02>*<2A>*<2A>*<2A>*<2A>*<2A>*<2A>s<EFBFBD>*<2A>*<2A>*<2A>s<EFBFBD>*<2A>*<2A>*<2A>*<2A>*<2A>*<2A>#<23>*<2A>*<2A>*<2A>#<23>*<2A>*<2A>*<2A>$<24>*<2A>*<2A>*<2A><02>*<2A>*<2A>*<2A>*<2A>*<2A>*<2A>*rN)r<>r<>r<>r<>r<>r<>r<>r<>r<>rrr<>r<>s<00><00>3<>I<01>0<> *<2A>
+rr<>c<00>.<00>eZdZdZd<02>Zd<03>Zd<04>Zd<05>Zd<06>Zy)<08>TestMemoryBoundsz#No buffer overflows in bit packing.c<00><><00>tjjd<01>jtj<00>}t |<01>\}}t |<02>}d}||k(}|<06>stjd|fd||f<02>dtj<00>vstjt <00>rtjt <00>nddtj<00>vstj|<02>rtj|<02>ndtj|<04>tj|<05>d<07>z}tjdt |<02><00><00><02>d zd
|iz}ttj|<08><00><00>dx}x}}y) Nr9rxr<>r<>r r*r<><00>Wrong packed size: <20>
>assert %(py8)srf<00>rrErGrHrIr+r rKrLrMrNrOrPrQrRrS<00> rUrr*<00>_rWr<>rlr<>r<>s r<00>test_packed_size_d64z%TestMemoryBounds.test_packed_size_d641s<><00><00> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>B<EFBFBD> <1F> &<26> &<26>r<EFBFBD>z<EFBFBD>z<EFBFBD> 2<><01>&<26>q<EFBFBD>)<29> <09><06><01><12>6<EFBFBD>{<7B>E<>b<EFBFBD>E<>{<7B>b<EFBFBD> <20>E<>E<>E<>{<7B>b<EFBFBD>E<>E<>E<>E<>E<>E<>s<EFBFBD>E<>E<>E<>s<EFBFBD>E<>E<>E<>E<>E<>E<>6<EFBFBD>E<>E<>E<>6<EFBFBD>E<>E<>E<>{<7B>E<>E<>E<>b<EFBFBD>E<>E<>E<>$7<><03>F<EFBFBD> <0B>}<7D>"E<>E<>E<>E<>E<>E<>E<>Erc<00><><00>tjjd<01>jtj<00>}t |<01>\}}t |<02>}d}||k(}|<06>stjd|fd||f<02>dtj<00>vstjt <00>rtjt <00>nddtj<00>vstj|<02>rtj|<02>ndtj|<04>tj|<05>d<07>z}tjdt |<02><00><00><02>d zd
|iz}ttj|<08><00><00>dx}x}}y) Nr]r9r<>r<>r r*r<>r<>r<>rfr<>r<>s r<00>test_packed_size_d128z&TestMemoryBounds.test_packed_size_d1286s<><00><00> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01>&<26>q<EFBFBD>)<29> <09><06><01><12>6<EFBFBD>{<7B>E<>b<EFBFBD>E<>{<7B>b<EFBFBD> <20>E<>E<>E<>{<7B>b<EFBFBD>E<>E<>E<>E<>E<>E<>s<EFBFBD>E<>E<>E<>s<EFBFBD>E<>E<>E<>E<>E<>E<>6<EFBFBD>E<>E<>E<>6<EFBFBD>E<>E<>E<>{<7B>E<>E<>E<>b<EFBFBD>E<>E<>E<>$7<><03>F<EFBFBD> <0B>}<7D>"E<>E<>E<>E<>E<>E<>E<>Erc<00><><00>tjjd<01>jtj<00>}t |<01>\}}t |<02>}d}||k(}|<06>stjd|fd||f<02>dtj<00>vstjt <00>rtjt <00>nddtj<00>vstj|<02>rtj|<02>ndtj|<04>tj|<05>d<07>z}tjdt |<02><00><00><02>d zd
|iz}ttj|<08><00><00>dx}x}}y) Nrar]r<>r<>r r*r<>r<>r<>rfr<>r<>s r<00>test_packed_size_d256z&TestMemoryBounds.test_packed_size_d256;s<><00><00> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01>&<26>q<EFBFBD>)<29> <09><06><01><12>6<EFBFBD>{<7B>F<>c<EFBFBD>F<>{<7B>c<EFBFBD>!<21>F<>F<>F<>{<7B>c<EFBFBD>F<>F<>F<>F<>F<>F<>s<EFBFBD>F<>F<>F<>s<EFBFBD>F<>F<>F<>F<>F<>F<>6<EFBFBD>F<>F<>F<>6<EFBFBD>F<>F<>F<>{<7B>F<>F<>F<>c<EFBFBD>F<>F<>F<>%8<><13>V<EFBFBD><1B> <0A>#F<>F<>F<>F<>F<>F<>F<>Frc<00><><00>tjjd<01>jtj<00>}t |<01>\}}|D<00>]<5D>}|dz}|dz }d}||k}|s<>t jd|fd||f<02>dtj<00>vst j|<05>rt j|<05>ndt j|<07>d<08>z} t jd |<05><00><02>d
zd | iz}
tt j|
<EFBFBD><00><00>d x}}d}||k}|s<>t jd|fd||f<02>d tj<00>vst j|<06>rt j|<06>nd t j|<07>d<08>z} t jd|<06><00><02>d
zd | iz}
tt j|
<EFBFBD><00><00>d x}}<07><01><>y )z/Packed bytes should only use 4 bits per nibble.r]r-rr<>r:r<<00>lowr>zLow nibble out of range: rBrCN<>highzHigh nibble out of range: )rrErGrHrIr+rKrLrMrNrOrPrQrRrS) rUrr*r<><00>byter<65>r<>rWrXrYrZs r<00>test_packed_values_in_rangez,TestMemoryBounds.test_packed_values_in_range@s)<00><00> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01>&<26>q<EFBFBD>)<29> <09><06><01><1B> B<01>D<EFBFBD><16><14>+<2B>C<EFBFBD><17>1<EFBFBD>9<EFBFBD>D<EFBFBD><1B> ><3E>3<EFBFBD><12>8<EFBFBD> ><3E> ><3E> ><3E>3<EFBFBD><12> ><3E> ><3E> ><3E> ><3E> ><3E> ><3E>3<EFBFBD> ><3E> ><3E> ><3E>3<EFBFBD> ><3E> ><3E> ><3E><12> ><3E> ><3E> ><3E>8<><13><05>><3E> ><3E> ><3E> ><3E> ><3E> ><3E> ><3E><1C> A<>4<EFBFBD>"<22>9<EFBFBD> A<> A<> A<>4<EFBFBD>"<22> A<> A<> A<> A<> A<> A<>4<EFBFBD> A<> A<> A<>4<EFBFBD> A<> A<> A<>"<22> A<> A<> A<> :<3A>4<EFBFBD>&<26>A<> A<> A<> A<> A<> A<> A<> A<>  Brc<00><><00>tjjd<01>jtj<00>}t |<01>\}}tj dtj<00><02>}td<01>D]'}|dzdk(r||dzdz||<<00>||dzdz ||<<00>)t||d<01>}t|<06>}|tjj|<07>dzz }tj dtj<00><02>} td<01>D]7}tjtj||tz
<00><00>| |<<00>9tj }
|| k(} |
| <0B>} | <0C>sMt#j$d| fd || f<02>d
t'j(<00>vst#j*|<04>rt#j,|<04>nd
d t'j(<00>vst#j*| <09>rt#j,| <09>nd d <0C>z} t#j.d <0A>dzdt'j(<00>vst#j*t<00>rt#j,t<00>ndt#j,|
<EFBFBD>| t#j,| <0C>d<10>z}t1t#j2|<0E><00><00>dx}
x} } y)zVerify pack/unpack symmetry.r]rr rr-rrr<>)z%(py3)s == %(py5)s<>indices_encode<64>indices_decode)r@rCzPack/unpack mismatchzG
>assert %(py9)s
{%(py9)s = %(py2)s
{%(py2)s = %(py0)s.all
}(%(py7)s)
}r)r?rdr<>r<>N)rrErGrHrIr+rr r r/rrrr#r!r"<00>allrKrLrMrNrOrPrQrRrS)rUrr*rr<>r<00>decodedr&r'r<>rXrlr<>rZ<00> @py_format10s r<00>test_unpack_matches_packz)TestMemoryBounds.test_unpack_matches_packLs<><00><00> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01>)<29>!<21>,<2C> <0C><06><04><1C><18><18>#<23>R<EFBFBD>X<EFBFBD>X<EFBFBD>6<><0E><16>s<EFBFBD><1A> 8<>A<EFBFBD><10>1<EFBFBD>u<EFBFBD><01>z<EFBFBD>$*<2A>1<EFBFBD><01>6<EFBFBD>N<EFBFBD>T<EFBFBD>$9<><0E>q<EFBFBD>!<21>$*<2A>1<EFBFBD><01>6<EFBFBD>N<EFBFBD>a<EFBFBD>$7<><0E>q<EFBFBD>!<21>  8<>%<25>V<EFBFBD>T<EFBFBD>3<EFBFBD>7<><07><16>w<EFBFBD>-<2D><07><1C><02> <09> <09><0E><0E>w<EFBFBD> 7<>$<24> ><3E>?<3F>
<EFBFBD><1B><18><18>#<23>R<EFBFBD>X<EFBFBD>X<EFBFBD>6<><0E><16>s<EFBFBD><1A> T<01>A<EFBFBD> "<22> <09> <09>"<22>&<26>&<26><1A>A<EFBFBD><1D>AQ<41>1Q<31>*R<> S<>N<EFBFBD>1<EFBFBD> <1D> T<01><12>v<EFBFBD>v<EFBFBD>O<>n<EFBFBD><0E>6<>O<>v<EFBFBD>O<>7<>O<>7<>O<>O<>O<>n<EFBFBD><0E>O<>O<>O<>O<>O<>O<>n<EFBFBD>O<>O<>O<>n<EFBFBD>O<>O<>O<>O<>O<>O<><0E>O<>O<>O<><0E>O<>O<>O<>O<>9O<39>O<>O<>O<>O<>O<>O<>r<EFBFBD>O<>O<>O<>r<EFBFBD>O<>O<>O<>v<EFBFBD>O<>O<>O<>7<>O<>O<>O<>O<>O<>OrN) r<>r<>r<>r<>r<>r<>r<>r<>r<>r<>rrr<>r<>.s#<00><00>-<2D>F<01>
F<01>
G<01>
B<01>Prr<>c<00><00>eZdZdZd<02>Zy)<04>TestCompressionRatioz/Verify the compression achieves expected ratio.c<00><><00>tjjd<01>jtj<00>}|j
}t |<01>\}}|j
dz}||z }d}||kD}|s<>tjd|fd||f<02>dtj<00>vstj|<06>rtj|<06>ndtj|<07>d<07>z} tjd|<06><00><02>d zd
| iz}
ttj|
<EFBFBD><00><00>d x}}d }||k}|s<>tjd |fd||f<02>dtj<00>vstj|<06>rtj|<06>ndtj|<07>d<07>z} tjd|<06><00><02>d zd
| iz}
ttj|
<EFBFBD><00><00>d x}}y )z94-bit quantization should give 8x compression vs float32.r]rg@r<>r<><00>ratior>zCompression ratio too low: rBrCNg!@r:r<zCompression ratio too high: )rrErGrHrI<00>nbytesr+rKrLrMrNrOrPrQrRrS) rUr<00>original_bytesr*r<00>compressed_bytesr<73>rWrXrYrZs r<00>test_4bit_compression_ratioz0TestCompressionRatio.test_4bit_compression_ratiols$<00><00> <0E>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD> <20> '<27> '<27><02>
<EFBFBD>
<EFBFBD> 3<><01><1A><18><18><0E>)<29>!<21>,<2C> <0C><06><04>!<21>=<3D>=<3D>1<EFBFBD>,<2C><18><1E>!1<>1<><05><1A>A<>u<EFBFBD>s<EFBFBD>{<7B>A<>A<>A<>u<EFBFBD>s<EFBFBD>A<>A<>A<>A<>A<>A<>u<EFBFBD>A<>A<>A<>u<EFBFBD>A<>A<>A<>s<EFBFBD>A<>A<>A<>9<>%<25><17>A<>A<>A<>A<>A<>A<>A<><1A>B<>u<EFBFBD>s<EFBFBD>{<7B>B<>B<>B<>u<EFBFBD>s<EFBFBD>B<>B<>B<>B<>B<>B<>u<EFBFBD>B<>B<>B<>u<EFBFBD>B<>B<>B<>s<EFBFBD>B<>B<>B<>:<3A>5<EFBFBD>'<27>B<>B<>B<>B<>B<>B<>BrN)r<>r<>r<>r<>r<>r<>rrr<>r<>is <00><00>9<>
Crr<>)r<><00>builtinsrM<00>_pytest.assertion.rewrite<74> assertion<6F>rewriterK<00>numpyr<00>pytestr|rIr"<00>ndarrayr<00>tupler2r+<00>intr/r4r6r<>r<>r<>r<>r<>r<>rr<00><module>r<>s <00><01> <04><01><00><12> <0A><1C>2<EFBFBD>8<EFBFBD>8<EFBFBD><02>
<0C><1A><1A> <15><10> <0A>B<EFBFBD>J<EFBFBD>J<EFBFBD> <0A>2<EFBFBD>:<3A>:<3A> <0A>$<18>B<EFBFBD>J<EFBFBD>J<EFBFBD><18>5<EFBFBD><12><1A><1A>U<EFBFBD>1B<31>+C<><18>><0F>r<EFBFBD>z<EFBFBD>z<EFBFBD><0F><15><0F>3<EFBFBD><0F>2<EFBFBD>:<3A>:<3A><0F>8<1F>R<EFBFBD>Z<EFBFBD>Z<EFBFBD><1F>B<EFBFBD>J<EFBFBD>J<EFBFBD><1F>5<EFBFBD><1F>:L<01>:L<01>B"I<01>"I<01>R)F<01>)F<01>`+<2B>+<2B>>4P<01>4P<01>v C<01> Cr