Skip to content

rp2/CMakeLists.txt: Enable float-abi=hard on RP2350 ARM boards. - #19661

Open
dpgeorge wants to merge 1 commit into
micropython:masterfrom
dpgeorge:rp2-enable-hard-float-abi
Open

rp2/CMakeLists.txt: Enable float-abi=hard on RP2350 ARM boards.#19661
dpgeorge wants to merge 1 commit into
micropython:masterfrom
dpgeorge:rp2-enable-hard-float-abi

Conversation

@dpgeorge

Copy link
Copy Markdown
Member

Summary

Prior to pico-sdk 2.3.0 all RP230 ARM boards were built unconditionally with -mfloat-abi=softfp, which uses hardware instructions for float operations but passes float arguments in integer registers. That's incompatible with MicroPython's native .mpy ABI, which expects float arguments to be passed in the float registers.

In 2.3.0 pico-sdk added PICO_HARD_FLOAT_ABI which allows the build to select -mfloat-abi=hard, passing floats in float registers. Enable that option on all RP2350 ARM boards so they can import and use native .mpy files containing float code.

Testing

Built various RP2040 and RP2350 boards. RP2040 still uses float-abi=soft and RP2350-RISC-V still doesn't use that option (it's a different arch), but RP2350 now uses float-abi=hard.

Tested on RPI_PICO2. Prior to this change running natmods would give:

$ ./run-natmodtests.py -t a0 extmod/random_*.py
platform=rp2 arch=armv7emsp
pass  extmod/random_basic.py
FAIL  extmod/random_extra_float.py - ('exception', b'START TEST\r\nrandom\r\n', b'Traceback (most recent call last):\r\n  File "<stdin>", line 44, in <module>\r\nAssertionError: \r\n')
pass  extmod/random_extra.py
SKIP  extmod/random_seed_default.py
3 tests performed
2 tests passed
1 tests skipped: extmod/random_seed_default.py
1 tests failed: extmod/random_extra_float.py

But now with this PR it gives:

$ ./run-natmodtests.py -t a0 extmod/random_*.py
platform=rp2 arch=armv7emsp
pass  extmod/random_basic.py
pass  extmod/random_extra_float.py
pass  extmod/random_extra.py
SKIP  extmod/random_seed_default.py
3 tests performed
3 tests passed
1 tests skipped: extmod/random_seed_default.py

Performance benchmark shows:

diff of scores (higher is better)
N=100 M=100                        p0 ->        p1b         diff      diff% (error%)
bm_chaos.py                    377.31 ->     383.19 :      +5.88 =  +1.558% (+/-0.08%)
bm_fannkuch.py                  96.06 ->      88.42 :      -7.64 =  -7.953% (+/-0.05%)
bm_fft.py                     3386.57 ->    3410.59 :     +24.02 =  +0.709% (+/-0.01%)
bm_float.py                   6125.99 ->    5894.66 :    -231.33 =  -3.776% (+/-0.06%)
bm_hexiom.py                    52.39 ->      56.16 :      +3.77 =  +7.196% (+/-0.04%)
bm_nqueens.py                 4366.79 ->    4537.14 :    +170.35 =  +3.901% (+/-0.04%)
bm_pidigits.py                 971.54 ->     952.03 :     -19.51 =  -2.008% (+/-0.03%)
bm_wordcount.py                 73.36 ->      69.61 :      -3.75 =  -5.112% (+/-0.02%)
core_import_mpy_multi.py       500.41 ->     500.73 :      +0.32 =  +0.064% (+/-0.09%)
core_import_mpy_single.py       93.28 ->      93.38 :      +0.10 =  +0.107% (+/-0.23%)
core_locals.py                  50.91 ->      53.69 :      +2.78 =  +5.461% (+/-0.04%)
core_qstr.py                   195.57 ->     216.82 :     +21.25 = +10.866% (+/-0.08%)
core_str.py                     28.28 ->      29.75 :      +1.47 =  +5.198% (+/-0.05%)
core_yield_from.py             383.27 ->     383.20 :      -0.07 =  -0.018% (+/-0.01%)
misc_aes.py                    527.32 ->     539.77 :     +12.45 =  +2.361% (+/-0.05%)
misc_mandel.py                3698.31 ->    3924.44 :    +226.13 =  +6.114% (+/-0.05%)
misc_pystone.py               2469.38 ->    2597.39 :    +128.01 =  +5.184% (+/-0.07%)
misc_raytrace.py               374.12 ->     402.77 :     +28.65 =  +7.658% (+/-0.06%)
viper_call0.py                 568.47 ->     568.52 :      +0.05 =  +0.009% (+/-0.01%)
viper_call1a.py                554.25 ->     554.31 :      +0.06 =  +0.011% (+/-0.00%)
viper_call1b.py                455.01 ->     455.06 :      +0.05 =  +0.011% (+/-0.00%)
viper_call1c.py                462.04 ->     462.07 :      +0.03 =  +0.006% (+/-0.00%)
viper_call2a.py                544.19 ->     544.26 :      +0.07 =  +0.013% (+/-0.00%)
viper_call2b.py                404.68 ->     404.71 :      +0.03 =  +0.007% (+/-0.00%)

misc_mandel.py and misc_raytrace.py use floats and they are up in performance. bm_float.py is down... but not as much as mandel/raytrace are up. As usual performance is hard to measure on chips with caching, but the above looks pretty reasonable in terms of an overall small improvement (and at least it's not a big decrease).

Will also be tested by Octoprobe, which previously failed the above extmod/random_extra_float.py test.

Trade-offs and Alternatives

Could leave it using softfp and then add a way for .mpy files to support working with that ABI. @projectgus had an idea how to do that (adding shim functions to convert floats between integer and float args), but IMO it's pretty complicated to do that.

Generative AI

I did not use generative AI tools when creating this PR.

Prior to pico-sdk 2.3.0 all RP230 ARM boards were built unconditionally
with `-mfloat-abi=softfp`, which uses hardware instructions for float
operations but passes float arguments in integer registers.  That's
incompatible with MicroPython's native .mpy ABI, which expects float
arguments to be passed in the float registers.

In 2.3.0 pico-sdk added PICO_HARD_FLOAT_ABI which allows the build to
select `-mfloat-abi=hard`, passing floats in float registers.  Enable that
option on all RP2350 ARM boards so they can import and use native .mpy
files containing float code.

Signed-off-by: Damien George <damien@micropython.org>
@dpgeorge

Copy link
Copy Markdown
Member Author

@robert-hh related to this PR, it looks like mimxrt boards ADAFRUIT_METRO_M7, MAKERDIARY_RT1011_NANO_KIT, MIMXRT1010_EVK, MIMXRT1015_EVK and OLIMEX_RT1010 use -mfloat-abi=softfp. Can they be changed to use -mfloat-abi=hard? It's a one-line change in ports/mimxrt/Makefile for that. As above, it can be tested by running the natmod tests for the random module.

@github-actions

Copy link
Copy Markdown

Code size report:

Reference:  esp32: Make esp32.LDO objects static, release on soft reset. [f668077]
Comparison: rp2/CMakeLists.txt: Enable float-abi=hard on RP2350 ARM boards. [merge of cad868b]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@robert-hh

Copy link
Copy Markdown
Contributor

Tested with MAKERDIARY_RT1011_NANO_KIT and MIMXRT1015_EVK. It builds fine. Ran the tests from tests/float/.py and tests/extmod/random.py. The results look clean. From tests/float the double test are skipped, and the divmod test. Result from random*.py below.
Should I run other tests?

tests$ ./run-tests.py -t a0 extmod/random*.py
platform=mimxrt arch=armv7emsp inlineasm=thumb float=32-bit unicode
pass  extmod/random_basic.py 
pass  extmod/random_extra_float.py 
pass  extmod/random_extra.py 
pass  extmod/random_seed_default.py 
4 tests performed (17 individual testcases)
4 tests passed

@dpgeorge

Copy link
Copy Markdown
Member Author

Thanks! Please also run ./run-natmodtests.py -t a0 extmod/*.py, both before and after the change.

@robert-hh

Copy link
Copy Markdown
Contributor

It seems that I need more instructions to run the tests. All of them are skipped with messages like skip extmod/random_basic.py - mpy file not compiled.

@dpgeorge

Copy link
Copy Markdown
Member Author

To build the natmods use:

$ cd examples/natmod
$ for dir in */; do make -C $dir ARCH=armv7emsp; done

(armv7emsp should be the correct arch for single precision. The other options are armv7m and armv7emdp. You can build them all, they all exist side-by-side.)

@agatti

agatti commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

RP2040 still uses float-abi=soft and RP2350-RISC-V still doesn't use that option

s/still doesn't/can't/ :( The Hazard3 core has no floating point support whatsoever, unfortunately.

@robert-hh

Copy link
Copy Markdown
Contributor

Ok. Things improved. Before there have been fails for running out of memory, and one fail at extmod/random_extra_float.py. That one is gone after chaning to hard. Detailed summary below.

Makerdiary MD before:

35 tests performed
33 tests passed
6 tests skipped: extmod/deflate_decompress.py extmod/random_seed_default.py extmod/re_debug.py extmod/re_stack_overflow2.py extmod/re_sub.py extmod/re_sub_unmatched.py
2 tests failed: extmod/deflate_compress.py extmod/random_extra_float.py

FAIL  extmod/deflate_compress.py - ('exception', b"START TEST\r\nTrue\r\nb'micropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropython'\r\nTrue\r\nb'micropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropython'\r\nValueError\r\nOSError\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nRAW\r\nZLIB(9)\r\n", b'Traceback (most recent call last):\r\n  File "<stdin>", line 146, in <module>\r\n  File "<stdin>", line 102, in compress\r\nMemoryError: memory allocation failed\r\n')

FAIL  extmod/random_extra_float.py - ('exception', b'START TEST\r\nrandom\r\n', b'Traceback (most recent call last):\r\n  File "<stdin>", line 44, in <module>\r\nAssertionError: \r\n')


MIMXRT1015_EVK before:

35 tests performed
32 tests passed
6 tests skipped: extmod/deflate_decompress.py extmod/random_seed_default.py extmod/re_debug.py extmod/re_stack_overflow2.py extmod/re_sub.py extmod/re_sub_unmatched.py
3 tests failed: extmod/btree_closed.py extmod/deflate_compress.py extmod/random_extra_float.py

FAIL  extmod/btree_closed.py - ('exception', b'START TEST\r\n', b'Traceback (most recent call last):\r\n  File "<stdin>", line 46, in <module>\r\nMemoryError: memory allocation failed, allocating 8216 bytes\r\n')

FAIL  extmod/deflate_compress.py - ('exception', b"START TEST\r\nTrue\r\nb'micropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropython'\r\nTrue\r\nb'micropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropython'\r\nValueError\r\nOSError\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nRAW\r\nZLIB(9)\r\n", b'Traceback (most recent call last):\r\n  File "<stdin>", line 146, in <module>\r\n  File "<stdin>", line 102, in compress\r\nMemoryError: memory allocation failed\r\n')

FAIL  extmod/random_extra_float.py - ('exception', b'START TEST\r\nrandom\r\n', b'Traceback (most recent call last):\r\n  File "<stdin>", line 44, in <module>\r\nAssertionError: \r\n')


Makerdiary MD after:

35 tests performed
34 tests passed
6 tests skipped: extmod/deflate_decompress.py extmod/random_seed_default.py extmod/re_debug.py extmod/re_stack_overflow2.py extmod/re_sub.py extmod/re_sub_unmatched.py
1 tests failed: extmod/deflate_compress.py

FAIL  extmod/deflate_compress.py - ('exception', b"START TEST\r\nTrue\r\nb'micropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropython'\r\nTrue\r\nb'micropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropython'\r\nValueError\r\nOSError\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nRAW\r\nZLIB(9)\r\n", b'Traceback (most recent call last):\r\n  File "<stdin>", line 146, in <module>\r\n  File "<stdin>", line 102, in compress\r\nMemoryError: memory allocation failed\r\n')

MIMXRT1015_EVK after:

35 tests performed
33 tests passed
6 tests skipped: extmod/deflate_decompress.py extmod/random_seed_default.py extmod/re_debug.py extmod/re_stack_overflow2.py extmod/re_sub.py extmod/re_sub_unmatched.py
2 tests failed: extmod/btree_closed.py extmod/deflate_compress.py

FAIL  extmod/btree_closed.py - ('exception', b'START TEST\r\n', b'Traceback (most recent call last):\r\n  File "<stdin>", line 46, in <module>\r\nMemoryError: memory allocation failed, allocating 8216 bytes\r\n')

FAIL  extmod/deflate_compress.py - ('exception', b"START TEST\r\nTrue\r\nb'micropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropython'\r\nTrue\r\nb'micropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropythonmicropython'\r\nValueError\r\nOSError\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nTrue\r\nRAW\r\nZLIB(9)\r\n", b'Traceback (most recent call last):\r\n  File "<stdin>", line 146, in <module>\r\n  File "<stdin>", line 102, in compress\r\nMemoryError: memory allocation failed\r\n')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants