Skip to content

ENH: Support IEEE binary128 DLPack export - #32548

Closed
mwyau wants to merge 2 commits into
numpy:mainfrom
mwyau:enh/dlpack-ieee-quad-float128
Closed

mwyau wants to merge 2 commits into
numpy:mainfrom
mwyau:enh/dlpack-ieee-quad-float128

Conversation

@mwyau

@mwyau mwyau commented Sep 9, 2026 •

Copy link
Copy Markdown

PR summary

Export IEEE binary128 to DLPack

  • Export existing IEEE binary128 variables to DLPack kDLFloat, only on platforms where longdouble/float128 is already IEEE binary128.
  • Consumers such as nanobind can then import the variables as IEEE binary128.
  • On platform not supported such as x87 longdouble, it will throw a BufferError, same as the current behavior.

Validation

  • Local tests passed.

First time committer introduction

  • I maintain several atmospheric sciences packages and is a contributor to ducc and scipy.

AI Disclosure

  • ChatGPT and Codex were used to research the problem and propose solutions. I wrote the code myself.

@rgommers

rgommers commented Sep 9, 2026

Copy link
Copy Markdown
Member

Thanks for the interest @mwyau. This doesn't work as long as DLPack doesn't support it, and as I commented on dmlc/dlpack#185 (comment), long double format support seems like the wrong ask here. You might want to rephrase it separate from that though, if it's only about proper quadruple-precision.

I maintain several atmospheric sciences packages and is a contributor to the ducc package.

ducc is C++, so couldn't you aim for std::float128_t.

You may also be interested in https://github.com/numpy/numpy-quaddtype, which is a proper 128-bit dtype and will hopefully supersede numpy's longdouble dtype.

@seberg

seberg commented Sep 9, 2026 •

Copy link
Copy Markdown
Member

Yeah it works (assuming the #define there is precise), dlpack says that this denotes a 128bit IEEE float.

But that doesn't answer if we actually should do it. longdouble is only an IEEE 128bit float on very few platforms in practice after all.

On the other hand, numpy-quaddtype can register it with NumPy 2.5+ to work (I am not sure it already did).
So my reservation about this is that numpy-quaddtype is the better target here for consistent behavior/expectation across platforms and since I suspect that a PR didn't land there yet, a PR there would be cool.

EDIT: To be clear, it may be possible to convince me, but in practice the numpy-quaddtype route seems the "obvious" one while such longdouble related improvements come with long-term doubt.

@mwyau mwyau changed the title ENH: Add IEEE quad longdouble to DLPack ENH: Support IEEE binary128 floating-point in DLPack Sep 9, 2026
@mwyau

mwyau commented Sep 9, 2026 •

Copy link
Copy Markdown
Author

@rgommers I should have rephrased my wording, this is not about adding long double support, but to allow IEEE binary 128 float to be accepted by DLPack, on supported platforms such as arm64.

ducc use C++ long double abstraction for cross-platform support and can't use float128_t directly:
https://github.com/mreineck/ducc/blob/5cc99a806f964c3fdc5f0ccea6a46977e23a1c41/python/fft_pymod.cc#L60

ducc's FFT module is a continuation of pocketfft by the same author. pocketfft/ducc is numpy and scipy's FFT backend: https://github.com/numpy/numpy/blob/88ddb9806d42f6a96dca9fa0870092d679117258/numpy/fft/_pocketfft.py https://github.com/numpy/numpy/blob/88ddb9806d42f6a96dca9fa0870092d679117258/numpy/fft/_pocketfft_umath.cpp And I do think there are use cases for high precision FFT support through long double/IEEE binary128 on supported platforms.

I have also opened a nanobind discussion: wjakob/nanobind#1432 (comment) I think the cleanest way is still to support it here in Numpy's DLPack interface since DLPack already support this format.

@hpkfft

hpkfft commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

ducc use C++ long double abstraction for cross-platform support and can't use float128_t directly

I see, of course, that it currently uses long double, but I don't see why it cannot use std::float128_t instead.
If a platform does not support std::float128_t, one could make the choice to support only float and double.
That seems reasonable to me. It looks like that's already done, for example, if long double is the same as double, which I think is microsoft's implementation.

@hpkfft

hpkfft commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

BTW, both long double and std::float128_t are supported on x86 by GCC. The former is 80 bits, padded to 128.
https://godbolt.org/z/WYcvcj1cP

@mwyau

mwyau commented Sep 10, 2026 •

Copy link
Copy Markdown
Author

This is more general than ducc, as I am targeting nanobind to add long double and complex<long double> support. They are the last remaining C++17 floating point types not supported by nanobind.

Both ducc and nanobind are targeting C++17, and for portable builds I think they cannot use C++23 fixed-width types such as std::float128_t.

It will be nice if Numpy can accept real IEEE binary128 directly, if not they can be passed through PEP 3118 buffer protocol.

Here is how long double presents on different platforms. Linux AArch64 is what I am focusing on lately.

Platform long double
Linux x86-64 x87 80-bit, 16 bytes
Linux AArch64 IEEE binary128, 16 bytes
macOS x86-64 x87 80-bit, 16 bytes
macOS ARM64 binary64, 8 bytes
Windows x86-64 binary64, 8 bytes
Windows ARM64 binary64, 8 bytes

@hpkfft

hpkfft commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

In other words, for portable builds one cannot use long double.

Note that nanobind already supports any floating-point type that DLPack supports, including IEEE binary128. If DLPack chooses to support complex binary128, nanobind will support it too. The problem with the last one is DLPack. See dmlc/dlpack#73
See https://nanobind.readthedocs.io/en/latest/ndarray.html#nonstandard-arithmetic-types

The problem with the buffer protocol is that PEP 3118 is marked as a historical document and advises the reader to refer to up-to-date canonical documentation. The type codes for struct don't mention long double. Neither does array.

My advice would be to try to revive interest in dmlc/dlpack#73

Is there any ARM hardware that supports IEEE binary128 arithmetic?
The ARM SVE docs state that the scalable vectors

Can hold 64, 32, 16, and 8-bit elements

@mwyau

mwyau commented Sep 10, 2026 •

Copy link
Copy Markdown
Author

Is there any ARM hardware that supports IEEE binary128 arithmetic?

I am aware that the ARM hardware does not support IEEE binary128 arithmetic. But Linux AArch64 is the only mainstream platform that support IEEE binary128 data type.

@hpkfft

hpkfft commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Huh? Most people would consider Linux x86_64 to be mainstream. Did you not read my post above? Or, do you mean you want a mainstream platform and compiler tool chain that implements long double as IEEE binary128?

@seberg

seberg commented Sep 10, 2026

Copy link
Copy Markdown
Member

Well, let me ignore the "do we even want to improve longdouble" part...

Doing this still seems unclear. You basically just support one toolchain/system setup that happens to use IEEE 128bit floats for longdouble, while on all other platforms there is no gain. And on the platform where it does work, it could get confusing if you mix in numpy-quaddtype because that platform might use numpy longdouble rather than numpy-quaddtype.

long double isn't the most appealing issue, to really make it work across platforms, you'd need to represent it in dlpack (and only IEEE 128 floats can be right now). Worse, the trivial way of just adding a type number, might mean adding a couple of them if you don't want it to be "system longdouble".

@mwyau

mwyau commented Sep 13, 2026 •

Copy link
Copy Markdown
Author

@seberg @rgommers
After looking deeper into how nanobind works, I changed this PR to export only:

  • Export IEEE binary128 to DLPack only on platforms where longdouble is IEEE binary128.
  • I removed the case 128 block for importing from DLPack.

The use case is:

  1. Although float128/longdouble is platform dependent, it is a basic C/C++ datatype. As we know, in Numpy np.float128 is an alias of np.longdouble.
  2. nanobind and other low level C++17 libraries such as ducc cannot easily move to std::float128_t. Currently the longdouble binding is missing from nanobind, that prevents migration from pybind11.
  3. This PR allows numpy to export existing IEEE binary128 variables to DLPack kDLFloat, only on platforms where longdouble/float128 is already IEEE binary128. Then nanobind can import the variables as IEEE binary128.
  4. On platform not supported such as x87 longdouble, it will throw a BufferError, same as the current behavior.

Separately I will look into how to use numpy-quaddtype directly in my project.

@mwyau mwyau changed the title ENH: Support IEEE binary128 floating-point in DLPack ENH: Support IEEE binary128 longdouble DLPack export Sep 13, 2026
@mwyau mwyau changed the title ENH: Support IEEE binary128 longdouble DLPack export ENH: Support IEEE binary128 DLPack export Sep 13, 2026
@mwyau
mwyau force-pushed the enh/dlpack-ieee-quad-float128 branch from af870ee to e5d4c01 Compare September 13, 2026 02:57
@mwyau

mwyau commented Sep 13, 2026 •

Copy link
Copy Markdown
Author

I have looked into this a bit more, and indeed importing float128 from DLPack is problematic:

  1. If the 128-bit float import is implemented as in the first commit, it will work on native IEEE binary128 supported machines.
  2. However it will override numpy.quaddtype's ability to register a QuadPrecDType with DLPack, which leads to inconsistent behaviors on different platforms.
  3. By changing this PR to export only, numpy can export float128 to DLPack kDLFloat directly only when it knows it is a real IEEE binary128.

This PR fills in the missing piece that float128 cannot be exported despite DLPack's ABI kDLFloat supports it.

@seberg seberg added 57 - Close? Issues which may be closable unless discussion continued and removed 57 - Close? Issues which may be closable unless discussion continued labels Sep 30, 2026
@seberg

seberg commented Sep 30, 2026

Copy link
Copy Markdown
Member

Currently, I don't think there is any agreement that doing this is even helpful (i.e. quaddtype is more obvious) as it would be only a rather niche platform actually using it.

So I'll close it as I don't really see it going anywhere at quite this time. Happy to keep the discussion up/re-open, but I think numpy-quaddtype should be the next step probably.

@seberg seberg closed this Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants