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: "TestMicroNumPy::()::test_reduce_logical_and"=
; but I don'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'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',)<br><could not determine information><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<=
;Guard0x4005356a88>)<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>)<br>=C2=A0 =C2=A0 f41 =3D raw_load_f(i9, i35, descr=
=3D<ArrayF 8>)<br>=C2=A0 =C2=A0 i43 =3D float_ne(f41, 0.000000)<br>=
=C2=A0 =C2=A0 guard_true(i43, descr=3D<Guard0x40053a0e60>)<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<Guard0x40053a0e90>)<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<ArrayF 8>)<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't understand why the backend can affect the logs in the =
9;jit-log-opt-' 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 <<a href=3D"mailto:tzuhsiang.chi=
[email protected]">[email protected]</a>> 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 <<a href=3D"mai=
lto:[email protected]" target=3D"_blank">[email protected]</a>> 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 <<a href=3D"mailto:tzuhsiang.c=
[email protected]" target=3D"_blank">[email protected]</a>> wrote:<=
br>
> > This should just be #defined to do nothing with Boehm, maybe in r=
python/translator/c/src/mem.h<br>
><br>
> 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>
> This configuration (JIT+BoehmGC) can pass test_tokenize and test_zipfi=
le64 (from lib_python_tests.py).<br>
><br>
> 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'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'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's also possible the bug is somewhere unrelated<b=
r>
and it'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==--