Re: Contribute a RISC-V 64 JIT backend

Logan Chien <[email protected]> Wed, 28 Feb 2024 23:34:40 -0800
Newsgroups gmane.comp.python.pypy
Message-ID <CALQyFuDeMzW1AWoQdBdS0NtB0ipnZXZ7oFOS1E_B0GrHfYptBA@mail.gmail.com>
--===============2021556517333102902==
Content-Type: multipart/alternative; boundary="0000000000007852500612804b48"

--0000000000007852500612804b48
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi all,

I am looking into the last failing case:
"TestMicroNumPy::()::test_reduce_logical_and" but I don't quite understand
what this test means.

The test case fails with:

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Loops don't match
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
loop id =3D None
('operation mismatch',)
<could not determine information>

Ignore ops: []
Got:

        =3D=3D=3D=3D=3D HERE =3D=3D=3D=3D=3D
    guard_not_invalidated(descr=3D<Guard0x4005356a88>)
    i39 =3D int_and(i35, 7)
    i40 =3D int_is_zero(i39)
    guard_true(i40, descr=3D<Guard0x40053a0e30>)
    f41 =3D raw_load_f(i9, i35, descr=3D<ArrayF 8>)
    i43 =3D float_ne(f41, 0.000000)
    guard_true(i43, descr=3D<Guard0x40053a0e60>)
    i45 =3D int_add(i28, 1)
    i47 =3D int_add(i35, 8)
    i48 =3D int_ge(i45, i36)
    guard_false(i48, descr=3D<Guard0x40053a0e90>)
    jump(p29, i45, p2, i47, p4, p6, i9, i36,
descr=3DTargetToken(274965300512))

Expected:


    i10096 =3D int_and(i29, 7)
    i10097 =3D int_is_zero(i10096)
    guard_true(i10097, descr=3D...)

        guard_not_invalidated(descr=3D...)
        f31 =3D raw_load_f(i9, i29, descr=3D<ArrayF 8>)
        i32 =3D float_ne(f31, 0.000000)
        guard_true(i32, descr=3D...)
        i36 =3D int_add(i24, 1)
        i37 =3D int_add(i29, 8)
        i38 =3D int_ge(i36, i30)
        guard_false(i38, descr=3D...)
        jump(..., descr=3D...)
```

IIUC, the difference is that guard_not_invalidated is at a different
location.

But I don't understand why the backend can affect the logs in the
'jit-log-opt-' tag.

Also, I found that reduce_logical_and (failed) and reduce_logical_xor
(passed) are very different.

Is there more information on the details of this test?  Any ideas to debug
this test case are very welcomed!  Thanks.

Regards,
Logan

p.s. I almost covered all the test cases.  Except the one described above,
other test cases are either Passing, classified as XFAIL (not supportable),
or related to environment (e.g. schroot/qemu).  I will try to run it on the
real board this weekend.


On Wed, Feb 21, 2024 at 9:57=E2=80=AFPM Logan Chien <tzuhsiang.chien@gmail.=
com>
wrote:

> Hi Armin,
>
> Thank you for the reply.
>
> Luckily, I found the bug.  It was a bug in my write barrier card marking
> implementation.  I misunderstood what AArch64 MVN instruction meant when =
I
> was porting the code.  After fixing it, I can pass these two test cases
> (test_zipfile64 and test_tokenize).
>
> Now, I am looking into test_json.  Earlier, I thought it was an XFAIL
> because the -O2 build was failing too.  But after adding
> `@settings(suppress_health_check=3D[HealthCheck.too_slow])` to
> `test_json.test_roundtrip`, I could run it in reasonable time.
>
> However, it was extremely slow when I ran the same test with the `-Ojit`
> build.  According to `PYPYLOG=3Djit:log.txt`, the JIT compiler kept build=
ing
> the same (or similar) bridge.  Statistics showed that the RISC-V JIT
> compiled more than 3000 bridges (when Ctrl-C interrupted) whereas the X86
> JIT build compiled only 900 bridges (when completed).  I will try to figu=
re
> out the failing guard op first.
>
> Regards,
> Logan
>
> On Mon, Feb 19, 2024 at 10:05=E2=80=AFPM Armin Rigo <[email protected]=
> wrote:
>
>> Hi Logan,
>>
>> On Tue, 20 Feb 2024 at 05:08, Logan Chien <[email protected]>
>> wrote:
>> > > This should just be #defined to do nothing with Boehm, maybe in
>> rpython/translator/c/src/mem.h
>> >
>> > With this change and a few RISC-V backend fixes (related to
>> self.cpu.vtable_offset), I can build and run a JIT+BoehmGC PyPy.
>>
>> Cool!  I also got a pull request merged into the main branch with this
>> change, and it does indeed fix boehm builds.
>>
>> > This configuration (JIT+BoehmGC) can pass test_tokenize and
>> test_zipfile64 (from lib_python_tests.py).
>> >
>> > Thus, my next step will focus on the differences between JIT+BoehmGC
>> and JIT+IncminimarkGC.
>>
>> A problem that came up a lot in other backends is a specific input
>> instruction that the backend emits with specific registers.  When you
>> run into the bad case, the emitted code reuses a register *before*
>> reading the same register assuming that it still contains its old
>> value.  It's entirely dependent on register allocation, and if you run
>> it with boehm then the sequence of instruction is slightly different
>> and that might be the reason that the bug doesn't show up then.  If
>> you get two failures with incminimark and none with boehm, then it
>> sounds more likely that the case involves one of the incminimark-only
>> constructions---but it's also possible the bug is somewhere unrelated
>> and it's purely bad luck...
>>
>>
>> Armin
>>
>

--0000000000007852500612804b48
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hi all,</div><div><br></div><div>I am looking into th=
e last failing case: &quot;TestMicroNumPy::()::test_reduce_logical_and&quot=
; but I don&#39;t quite understand what this test means.</div><div><br></di=
v><div>The test case fails with:</div><div><br></div><div>```<br></div><div=
>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<br>Loops don&#39;t match<br>=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>loop id =3D None<br>(&#=
39;operation mismatch&#39;,)<br>&lt;could not determine information&gt;<br>=
<br>Ignore ops: []<br>Got:<br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D=3D=3D=3D=
=3D HERE =3D=3D=3D=3D=3D<br>=C2=A0 =C2=A0 guard_not_invalidated(descr=3D&lt=
;Guard0x4005356a88&gt;)<br>=C2=A0 =C2=A0 i39 =3D int_and(i35, 7)<br>=C2=A0 =
=C2=A0 i40 =3D int_is_zero(i39)<br>=C2=A0 =C2=A0 guard_true(i40, descr=3D&l=
t;Guard0x40053a0e30&gt;)<br>=C2=A0 =C2=A0 f41 =3D raw_load_f(i9, i35, descr=
=3D&lt;ArrayF 8&gt;)<br>=C2=A0 =C2=A0 i43 =3D float_ne(f41, 0.000000)<br>=
=C2=A0 =C2=A0 guard_true(i43, descr=3D&lt;Guard0x40053a0e60&gt;)<br>=C2=A0 =
=C2=A0 i45 =3D int_add(i28, 1)<br>=C2=A0 =C2=A0 i47 =3D int_add(i35, 8)<br>=
=C2=A0 =C2=A0 i48 =3D int_ge(i45, i36)<br>=C2=A0 =C2=A0 guard_false(i48, de=
scr=3D&lt;Guard0x40053a0e90&gt;)<br>=C2=A0 =C2=A0 jump(p29, i45, p2, i47, p=
4, p6, i9, i36, descr=3DTargetToken(274965300512)) =C2=A0 <br><br>Expected:=
<br>=C2=A0 =C2=A0 <br>=C2=A0 =C2=A0 <br>=C2=A0 =C2=A0 i10096 =3D int_and(i2=
9, 7)<br>=C2=A0 =C2=A0 i10097 =3D int_is_zero(i10096)<br>=C2=A0 =C2=A0 guar=
d_true(i10097, descr=3D...)<br>=C2=A0 =C2=A0 <br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 guard_not_invalidated(descr=3D...)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f31 =
=3D raw_load_f(i9, i29, descr=3D&lt;ArrayF 8&gt;)<br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 i32 =3D float_ne(f31, 0.000000)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 guard=
_true(i32, descr=3D...)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 i36 =3D int_add(i24,=
 1)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 i37 =3D int_add(i29, 8)<br>=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 i38 =3D int_ge(i36, i30)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 guar=
d_false(i38, descr=3D...)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 jump(..., descr=3D=
...)</div><div>```<br></div><div><br></div><div>IIUC, the difference is tha=
t guard_not_invalidated is at a different location.</div><div><br></div><di=
v>But I don&#39;t understand why the backend can affect the logs in the &#3=
9;jit-log-opt-&#39; tag.</div><div><br></div><div>Also, I found that reduce=
_logical_and (failed) and reduce_logical_xor (passed) are very different.</=
div><div><br></div><div>Is there more information on the details of this te=
st?=C2=A0 Any ideas to debug this test case are very welcomed!=C2=A0 Thanks=
.</div><div><br></div><div>Regards,</div><div>Logan</div><div><br></div><di=
v>p.s. I almost covered all the test cases.=C2=A0 Except the one described =
above, other test cases are either Passing, classified as XFAIL (not suppor=
table), or related to environment (e.g. schroot/qemu).=C2=A0 I will try to =
run it on the real board this weekend.<br></div><div><br></div></div><br><d=
iv class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, Feb =
21, 2024 at 9:57=E2=80=AFPM Logan Chien &lt;<a href=3D"mailto:tzuhsiang.chi=
[email protected]">[email protected]</a>&gt; wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Hi Armin,</div=
><div><br></div><div>Thank you for the reply.</div><div><br></div><div>Luck=
ily, I found the bug.=C2=A0 It was a bug in my write barrier card marking i=
mplementation.=C2=A0 I misunderstood what AArch64 MVN instruction meant whe=
n I was porting the code.=C2=A0 After fixing it, I can pass these two test =
cases (test_zipfile64 and test_tokenize).</div><div><br></div><div>Now, I a=
m looking into test_json.=C2=A0 Earlier, I thought it was an XFAIL because =
the -O2 build was failing too.=C2=A0 But after adding `@settings(suppress_h=
ealth_check=3D[HealthCheck.too_slow])` to `test_json.test_roundtrip`, I cou=
ld run it in reasonable time.</div><div><br></div><div>However, it was extr=
emely slow when I ran the same test with the `-Ojit` build.=C2=A0 According=
 to `PYPYLOG=3Djit:log.txt`, the JIT compiler kept building the same (or si=
milar) bridge.=C2=A0 Statistics showed that the RISC-V JIT compiled more th=
an 3000 bridges (when Ctrl-C interrupted) whereas the X86 JIT build compile=
d only 900 bridges (when completed).=C2=A0 I will try to figure out the fai=
ling guard op first.</div><div><br></div><div>Regards,</div><div>Logan<br><=
/div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_a=
ttr">On Mon, Feb 19, 2024 at 10:05=E2=80=AFPM Armin Rigo &lt;<a href=3D"mai=
lto:[email protected]" target=3D"_blank">[email protected]</a>&gt; wr=
ote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Logan,<b=
r>
<br>
On Tue, 20 Feb 2024 at 05:08, Logan Chien &lt;<a href=3D"mailto:tzuhsiang.c=
[email protected]" target=3D"_blank">[email protected]</a>&gt; wrote:<=
br>
&gt; &gt; This should just be #defined to do nothing with Boehm, maybe in r=
python/translator/c/src/mem.h<br>
&gt;<br>
&gt; With this change and a few RISC-V backend fixes (related to self.cpu.v=
table_offset), I can build and run a JIT+BoehmGC PyPy.<br>
<br>
Cool!=C2=A0 I also got a pull request merged into the main branch with this=
<br>
change, and it does indeed fix boehm builds.<br>
<br>
&gt; This configuration (JIT+BoehmGC) can pass test_tokenize and test_zipfi=
le64 (from lib_python_tests.py).<br>
&gt;<br>
&gt; Thus, my next step will focus on the differences between JIT+BoehmGC a=
nd JIT+IncminimarkGC.<br>
<br>
A problem that came up a lot in other backends is a specific input<br>
instruction that the backend emits with specific registers.=C2=A0 When you<=
br>
run into the bad case, the emitted code reuses a register *before*<br>
reading the same register assuming that it still contains its old<br>
value.=C2=A0 It&#39;s entirely dependent on register allocation, and if you=
 run<br>
it with boehm then the sequence of instruction is slightly different<br>
and that might be the reason that the bug doesn&#39;t show up then.=C2=A0 I=
f<br>
you get two failures with incminimark and none with boehm, then it<br>
sounds more likely that the case involves one of the incminimark-only<br>
constructions---but it&#39;s also possible the bug is somewhere unrelated<b=
r>
and it&#39;s purely bad luck...<br>
<br>
<br>
Armin<br>
</blockquote></div>
</blockquote></div>

--0000000000007852500612804b48--

--===============2021556517333102902==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
pypy-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/pypy-dev.python.org/
Member address: [email protected]

--===============2021556517333102902==--