Skip to content

gh-153740: Optimize PyFloat_Pack/Unpack2 using native _Float16 - #154796

Merged
vstinner merged 27 commits into
python:mainfrom
skirpichev:use-_Float16/153740
Sep 1, 2026
Merged

gh-153740: Optimize PyFloat_Pack/Unpack2 using native _Float16#154796
vstinner merged 27 commits into
python:mainfrom
skirpichev:use-_Float16/153740

Conversation

@skirpichev

Copy link
Copy Markdown
Member Author

Not sure how to fix this error:

/usr/bin/ld: /usr/bin/ld: DWARF error: invalid or unhandled FORM value: 0x25
Objects/floatobject.o: in function `PyFloat_Pack2':
floatobject.c:(.text.PyFloat_Pack2[PyFloat_Pack2]+0x32): undefined reference to `__truncdfhf2'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

CC @StanFromIreland (fuzzers)

@StanFromIreland

Copy link
Copy Markdown
Member

The configure probe only tests a compile-time _Float16 constant, so it reports "yes" in the OSS-Fuzz Docker container where clang accepts the type but the container's pre-GCC-12 libgcc lacks __truncdfhf2 which is the runtime helper the PyFloat_Pack2 double to _Float16 conversion links against. I suggest you make configure do a runtime double to _Float16 conversion.

@skirpichev
skirpichev force-pushed the use-_Float16/153740 branch from 46fe384 to 8bda53a Compare July 30, 2026 00:18
@skirpichev

Copy link
Copy Markdown
Member Author

I suggest you make configure do a runtime double to _Float16 conversion.

Good idea, that works.

@skirpichev
skirpichev marked this pull request as ready for review July 30, 2026 01:03
Comment thread configure.ac Outdated
@skirpichev skirpichev added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jul 30, 2026
@bedevere-bot

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @skirpichev for commit ac38cb8 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F154796%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jul 30, 2026
@skirpichev skirpichev removed their assignment Jul 30, 2026
Comment thread configure.ac Outdated
Co-authored-by: hpkfft.com <paul@hpkfft.com>
uriesmooth

This comment was marked as spam.

@skirpichev skirpichev closed this Aug 13, 2026
@skirpichev
skirpichev deleted the use-_Float16/153740 branch August 13, 2026 12:01
@vstinner

Copy link
Copy Markdown
Member

@skirpichev: Did you close your PR on purpose?

@skirpichev

Copy link
Copy Markdown
Member Author

Did you close your PR on purpose?

Yes, this lacks benchmarks. I hope someone will continue this.

@skirpichev

Copy link
Copy Markdown
Member Author

@hpkfft, maybe you can check performance for a simple pyperf-based benchmark?

import pyperf
from struct import pack, unpack

x = 3.140625
bx = struct.pack('e', x)

runner = pyperf.Runner()
runner.bench_func('pack("e", 3.140625)', pack, "e", x)
runner.bench_func('unpack("e", b"HB")', unpack, "e", bx)

@hpkfft

hpkfft commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Using gcc 14.2.0 and ./configure:

main:
pack("e", 3.140625): Mean +- std dev: 56.2 ns +- 1.1 ns
unpack("e", b"HB"): Mean +- std dev: 64.8 ns +- 1.2 ns

patch:
pack("e", 3.140625): Mean +- std dev: 51.9 ns +- 0.8 ns
unpack("e", b"HB"): Mean +- std dev: 59.0 ns +- 1.0 ns

Using ./configure --enable-optimizations:

main:
pack("e", 3.140625): Mean +- std dev: 37.7 ns +- 0.2 ns
unpack("e", b"HB"): Mean +- std dev: 46.1 ns +- 0.4 ns

patch:
pack("e", 3.140625): Mean +- std dev: 38.2 ns +- 0.3 ns
unpack("e", b"HB"): Mean +- std dev: 43.6 ns +- 0.5 ns

Interesting. Does the training input for PGO have NaNs in it? If so, maybe it shouldn't....

@skirpichev
skirpichev restored the use-_Float16/153740 branch August 19, 2026 03:01
@skirpichev skirpichev reopened this Aug 19, 2026
@skirpichev

Copy link
Copy Markdown
Member Author

Does the training input for PGO have NaNs in it?

Yes, PGO set of tests lacks test_capi, but test_struct.py is selected (see Lib/test/libregrtest/pgo.py). That one has various tests, including half-float NaNs. You can filter out some tests for PGO by @skip_if_pgo_task. (Usually we do this for expensive tests.)

Apparently, CPython runtime overhead dominated in the above benchmark. For C code I got ~2x speedup, like you above. I'll try to repeat that with some benchmarking framework.

Anyway, lets reopen this.

@skirpichev
skirpichev requested a review from vstinner August 19, 2026 04:02

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good, the new code (since my previous review) is way shorter. Its size is now more acceptable to me.

Comment thread configure.ac Outdated
Comment thread Objects/floatobject.c Outdated
Comment thread Objects/floatobject.c
Comment thread Objects/floatobject.c
Comment thread Objects/floatobject.c
@skirpichev
skirpichev requested a review from vstinner August 31, 2026 23:48

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@vstinner
vstinner enabled auto-merge (squash) September 1, 2026 13:16
@vstinner
vstinner merged commit e7ef46a into python:main Sep 1, 2026
59 checks passed
@skirpichev
skirpichev deleted the use-_Float16/153740 branch September 1, 2026 13:17
@vstinner

vstinner commented Sep 1, 2026

Copy link
Copy Markdown
Member

Merged, thanks.

@vstinner

vstinner commented Sep 1, 2026

Copy link
Copy Markdown
Member

I didn't close #153740 since it seems like more changes are planned.

@bedevere-bot

Copy link
Copy Markdown

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot wasm32-wasi 3.x (tier-2) has failed when building commit e7ef46a.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/1046/builds/12907) and take a look at the build logs.
  4. Check if the failure is related to this commit (e7ef46a) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/1046/builds/12907

Failed tests:

  • test_zipfile

Failed subtests:

  • test_append_to_concatenated_zip_file - test.test_zipfile.test_core.StoredTestsWithSourceFile.test_append_to_concatenated_zip_file
  • test_write_filtered_python_package - test.test_zipfile.test_core.PyZipFileTests.test_write_filtered_python_package

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/Lib/test/test_zipfile/test_core.py", line 3649, in test_write_filtered_python_package
    with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
                               ~~~~~~~~~~~~~~~~~^^^^^^^^
  File "/Lib/zipfile/__init__.py", line 2026, in __exit__
    self.close()
    ~~~~~~~~~~^^
  File "/Lib/zipfile/__init__.py", line 2667, in close
    self.fp.seek(self.start_dir)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^
OSError: [Errno 51] No space left on device


Traceback (most recent call last):
  File "/Lib/test/test_zipfile/test_core.py", line 3654, in test_write_filtered_python_package
    zipfp.writepy(packagedir)
    ~~~~~~~~~~~~~^^^^^^^^^^^^
  File "/Lib/zipfile/__init__.py", line 2830, in writepy
    self.writepy(path, basename,
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^
                 filterfunc=filterfunc)  # Recursive call
                 ^^^^^^^^^^^^^^^^^^^^^^
  File "/Lib/zipfile/__init__.py", line 2840, in writepy
    self.writestr(arcname, bytecode)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/Lib/zipfile/__init__.py", line 2605, in writestr
    with self.open(zinfo, mode='w') as dest:
         ~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Lib/zipfile/__init__.py", line 1423, in close
    self._fileobj.seek(self._zinfo.header_offset)
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 51] No space left on device


Traceback (most recent call last):
  File "/Lib/test/test_zipfile/test_core.py", line 3649, in test_write_filtered_python_package
    with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp:
         ~~~~~~~~~~~~~^^
OSError: [Errno 51] No space left on device


Traceback (most recent call last):
  File "/Lib/test/test_zipfile/test_core.py", line 572, in test_append_to_concatenated_zip_file
    f.write(data)
    ~~~~~~~^^^^^^
OSError: [Errno 51] No space left on device

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants