You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm one of the NumPy maintainers. I'm also an engineer @Quansight-Labs. Last year as part of our internship program @SwayamInSync implemented a new 128 bit floating point data type for NumPy. See his blog post for more detail. You can also see the code here.
Our plan with the quaddtype is to provide a way for users of numpy.longdouble to have access to both a fast hardware 80 bit float as well as a float128 implementation provided by the SLEEF library. You can choose which "backend" you want to use at runtime.
We still have a bit more work to do to improve the packaging of numpy-quaddtype, but I'm also curious if what we have now is generally useful for pulsar timing work.
Thank you for your comments. We have been struggling with this issue for a while (see #1170). I did see the work you and @SwayamInSync did, and was very interested in it, but when I looked at the page I admit I was scared off by "These dtypes are not meant for real-world use yet." I did check back occasionally but didn't see any dramatic changes. But if you think it's ready for testing I will do that.
Or if I run the tests in the GitHub package, I get 779 failures (don't want to list them all). Is there something wrong with this installation procedure?
The incorrect in above step it seems from the output is that you installed the very older version from pip but since within the folder the python is searching APIs from the current project source
Looking at the issue you mentioned, it seems we have pretty much to be work as the alternative for xprec/ld mentioned in issue.
Let me know I can help in building a patch with numpy-quaddtype to test for that issue.
Thanks for the response. I am attempting to install from source but it's not entirely straightforward. So far I can get sleef installed but still having trouble with quaddtype itself.
For our user base having a package installation (pip and/or conda) is important, but it sounds like that's in your plans. Will that package include sleef as well?
Yes even the version uploaded currently of PyPI comes with included sleef. So we will be continuing with this it's just current source code has multiple better APIs and support so that's why I am recommending it.
Indeed, I could install it easily and run the sample code. Thanks! It will take longer to see how well this works for us. I tried to just look at the reported finfo but it seems like that's not available, and that you were aware of this (numpy/numpy#27231). So we may need to adjust our tests, but that should be doable.
Any suggestions for how to quickly test for the available precision without finfo? We had a number of tests that used finfo.eps.
OK, I finally got around to installing this on a machine under the arm platform. I used a fresh conda install and a fresh environment, with numpy-quaddtype installed through pip. But when I try some of the basic tests I get:
>>> import numpy_quaddtype as npq
OMP: Error numpy/numpy-user-dtypes#15: Initializing libomp.dylib, but found libomp.dylib already initialized.
OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program. That is dangerous, since it can degrade performance or cause incorrect results. The best thing to do is to ensure that only a single OpenMP runtime is linked into the process, e.g. by avoiding static linking of the OpenMP runtime in any library. As an unsafe, unsupported, undocumented workaround you can set the environment variable KMP_DUPLICATE_LIB_OK=TRUE to allow the program to continue to execute, but that may cause crashes or silently produce incorrect results. For more information, please see http://openmp.llvm.org/
I don't know if this is something specific to the machine or to how numpy-quaddtype was packaged. Any ideas?
I've never seem this before but IMO getting an error like this on import after installing a wheel is bu definition a bug in the quaddtype packaging. Would you mind filing an issue on the numpy-user-dtypes repo about this? It would also help to get information about your system and how you set up your Python environment so we can reproduce the issue.
OK, moving on now. One possible way to implement this is to monkey-patch np.longdouble to QuadPrecDType(backend="sleef"). But having a callable function of the dtype would help with that. Is that something that's in the works? I don't know the tradeoffs.
Long-term, we probably would need to write a NEP to add the dtype to numpy itself. Out of curiosity, why is monkeypatching numpy needed on your end? Is there a lot of code that uses string type codes or something like that?
Hi, @ngoldbaum and @SwayamInSync One issue I'm encountering now is that we store our data in astropy.table.Table objects and that works fine, but it fails when we try to stack two tables:
import numpy as np
from numpy_quaddtype import QuadPrecDType, QuadPrecision
from astropy.table import Table, Column, vstack
x1 = np.array(np.arange(10), dtype=QuadPrecDType)
t1 = Table([Column(x1, name="x")])
print(f"x.dtype={t1['x'].dtype}")
x2 = np.array(np.arange(10), dtype=QuadPrecDType)
t2 = Table([Column(x2, name="x")])
t = vstack([t1, t2])
so the last operation fails with:
515 if data is None:
--> 516 self_data = np.zeros((length,) + shape, dtype=dtype)
517 elif isinstance(data, BaseColumn) and hasattr(data, "_name"):
518 # When unpickling a MaskedColumn, ``data`` will be a bare
519 # BaseColumn with none of the expected attributes. In this case
520 # do NOT execute this block which initializes from ``data``
521 # attributes.
522 self_data = np.array(data.data, dtype=dtype, copy=copy)
TypeError: data type "QuadPrecDType(backend='sleef')" not understood
I don't know why this is happening here, since I can clearly create new arrays with that dtype. A workaround may be possible, but in case there was something obvious/subtle that I was missing, I thought I'd ask. Note that this is with astropy 8.0.
@mhvk do you happen to have any insight about the interaction between astropy and quaddtype described in the comment above? Hopefully Marten has a bit more context about this.
Interesting conversation! I've been meaning to try the quaddtype for astropy's Time (which currently uses two doubles), so nice to see the progress.
Directly related to here: The error message suggests it is not related to astropy since it is just trying to create a zero-filled array with np.zeros... (would check, but my office machine seems to old for numpy-quaddtype, I get an error on import, RuntimeError: Invalid slot with value 1031 passed in.)
Hi, @mhvk Nice to hear from you. I understand your point about this not being astropy related, but something like np.zeros((40,),dtype=QuadPrecDType) works just fine. So I don't know if somehow it's not seeing the import of that package. In my example I am creating arrays in that way to start.
Unfortunately I cannot figure out a more minimal example. That is my problem. Array creation on its own works fine, but somehow when this is done from within the table module it does not work. So I don't know if it's a subtle namespace issue or something else. If you have ideas about things to try I can do so.
Can you at least share the full traceback in e.g. a github gist? It's not clear to me where the snippet of your traceback comes from. Astropy internals?
It might also help to put a breakpoint right above the problematic np.zeros call to see exactly what dtype is (e.g. its type). Maybe the repr is fooling us?
Ah its the issue from astropy, they are storing the dtype as a string and then passing that string to create zeros, basically they are doing something as following
In [3]: np.zeros((40,), dtype="QuadPrecDType(backend='sleef')")
---------------------------------------------------------------------------TypeErrorTraceback (mostrecentcalllast)
CellIn[3], line1---->1np.zeros((40,), dtype="QuadPrecDType(backend='sleef')")
TypeError: data type "QuadPrecDType(backend='sleef')"notunderstood
They should just be storing it like a dtype object rather than string
Generally in numpy string parsing of dtype works, but this is a custom dtype, I am not sure whether there's a way to make custom dtype also get parsed in NumPy but TBH I don't like this method anyways
Ah, yes, I see. It sounds like @SwayamInSync identified the issue, but in case it's helpful the full traceback is:
---> 10 t = vstack([t1, t2])
File ~/miniforge3/envs/nptest2/lib/python3.13/site-packages/astropy/table/operations.py:715, in vstack(tables, join_type, metadata_conflicts)
712 if len(tables) == 1:
713 return tables[0] # no point in stacking a single table
--> 715 out = _vstack(tables, join_type, metadata_conflicts)
717 # Merge table metadata
718 _merge_table_meta(out, tables, metadata_conflicts=metadata_conflicts)
File ~/miniforge3/envs/nptest2/lib/python3.13/site-packages/astropy/table/operations.py:1492, in _vstack(arrays, join_type, metadata_conflicts)
1488 raise NotImplementedError(
1489 f"vstack unavailable for mixin column type(s): {col_cls.__name__}"
1490 )
1491 try:
-> 1492 col = col_cls.info.new_like(cols, n_rows, metadata_conflicts, out_name)
1493 except metadata.MergeConflictError as err:
1494 # Beautify the error message when we are trying to merge columns with incompatible
1495 # types by including the name of the columns that originated the error.
1496 raise TableMergeError(
1497 f"The '{out_name}' columns have incompatible types: "
1498 f"{err._incompat_types}"
1499 ) from err
File ~/miniforge3/envs/nptest2/lib/python3.13/site-packages/astropy/table/column.py:482, in ColumnInfo.new_like(self, cols, length, metadata_conflicts, name)
454 """
455 Return a new Column instance which is consistent with the
456 input ``cols`` and has ``length`` rows.
(...) 476
477 """
478 attrs = self.merge_cols_attributes(
479 cols, metadata_conflicts, name, ("meta", "unit", "format", "description")
480 )
--> 482 return self._parent_cls(length=length, **attrs)
File ~/miniforge3/envs/nptest2/lib/python3.13/site-packages/astropy/table/column.py:1246, in Column.__new__(cls, data, name, dtype, shape, length, description, unit, format, meta, copy, copy_indices)
1241 if isinstance(data, MaskedColumn) and np.any(data.mask):
1242 raise TypeError(
1243 "Cannot convert a MaskedColumn with masked value to a Column"
1244 )
-> 1246 self = super().__new__(
1247 cls,
1248 data=data,
1249 name=name,
1250 dtype=dtype,
1251 shape=shape,
1252 length=length,
1253 description=description,
1254 unit=unit,
1255 format=format,
1256 meta=meta,
1257 copy=copy,
1258 copy_indices=copy_indices,
1259 )
1260 return self
File ~/miniforge3/envs/nptest2/lib/python3.13/site-packages/astropy/table/column.py:516, in BaseColumn.__new__(cls, data, name, dtype, shape, length, description, unit, format, meta, copy, copy_indices)
501 def __new__(
502 cls,
503 data=None,
(...) 513 copy_indices=True,
514 ):
515 if data is None:
--> 516 self_data = np.zeros((length,) + shape, dtype=dtype)
517 elif isinstance(data, BaseColumn) and hasattr(data, "_name"):
518 # When unpickling a MaskedColumn, ``data`` will be a bare
519 # BaseColumn with none of the expected attributes. In this case
520 # do NOT execute this block which initializes from ``data``
521 # attributes.
522 self_data = np.array(data.data, dtype=dtype, copy=copy)
TypeError: data type "QuadPrecDType(backend='sleef')" not understood
Interesting conversation! I've been meaning to try the quaddtype for astropy's Time (which currently uses two doubles), so nice to see the progress.
Directly related to here: The error message suggests it is not related to astropy since it is just trying to create a zero-filled array with np.zeros... (would check, but my office machine seems to old for numpy-quaddtype, I get an error on import, RuntimeError: Invalid slot with value 1031 passed in.)
Hey @mhvk maybe you can raise the issue on quaddtype with some more info, The only requirement should be numpy>=2.4 because there we added an extra slot, so that might be missing if using older version.
Ah its the issue from astropy, they are storing the dtype as a string and then passing that string to create zeros, basically they are doing something as following
In [3]: np.zeros((40,), dtype="QuadPrecDType(backend='sleef')")
Okay so I was checking the numpy's string parsing of dtypes and found a workaround, @dlakaplan you might need to add this line in top of your code to make that work
Basically this registers the string variant of numpy_quaddtype into the sctypeDict hashmap. I will check with the team if we can expose a hook and make it work implicitly within the dtype but till then this hack will work
Activity
dlakaplan commentedon Aug 25, 2025
Thank you for your comments. We have been struggling with this issue for a while (see #1170). I did see the work you and @SwayamInSync did, and was very interested in it, but when I looked at the page I admit I was scared off by "These dtypes are not meant for real-world use yet." I did check back occasionally but didn't see any dramatic changes. But if you think it's ready for testing I will do that.
dlakaplan commentedon Aug 25, 2025
OK, I just started to test this but couldn't even get the suggested commands at https://github.com/numpy/numpy-user-dtypes/tree/main/quaddtype to run, or the packaged tests. I assume I must be doing something wrong since it seems there are others who have used this correctly. I can file an issue over on https://github.com/numpy/numpy-user-dtypes/tree/main/quaddtype if that's preferred, or if you have any suggestions here I would be grateful.
On a M2 Mac with x64 conda:
pip install numpy-quaddtypeOr if I run the tests in the GitHub package, I get 779 failures (don't want to list them all). Is there something wrong with this installation procedure?
SwayamInSync commentedon Aug 25, 2025
Hey @dlakaplan
You can follow the steps present here https://github.com/numpy/numpy-user-dtypes/tree/main/quaddtype#installation-from-source and please install from the source, pip version is pretty old (we will update it with the upcomong v1.0 release)
The incorrect in above step it seems from the output is that you installed the very older version from pip but since within the folder the python is searching APIs from the current project source
Looking at the issue you mentioned, it seems we have pretty much to be work as the alternative for xprec/ld mentioned in issue.
Let me know I can help in building a patch with numpy-quaddtype to test for that issue.
dlakaplan commentedon Aug 26, 2025
Thanks for the response. I am attempting to install from source but it's not entirely straightforward. So far I can get sleef installed but still having trouble with quaddtype itself.
For our user base having a package installation (pip and/or conda) is important, but it sounds like that's in your plans. Will that package include sleef as well?
SwayamInSync commentedon Aug 26, 2025
Yes even the version uploaded currently of PyPI comes with included sleef. So we will be continuing with this it's just current source code has multiple better APIs and support so that's why I am recommending it.
ngoldbaum commentedon Aug 26, 2025
There's a package on conda-forge too: https://anaconda.org/conda-forge/numpy_quaddtype
ngoldbaum commentedon Sep 12, 2025
@SwayamInSync did a bunch of work the last couple weeks to simplify the packaging situation. Maybe you can try again?
dlakaplan commentedon Sep 12, 2025
Indeed, I could install it easily and run the sample code. Thanks! It will take longer to see how well this works for us. I tried to just look at the reported
finfobut it seems like that's not available, and that you were aware of this (numpy/numpy#27231). So we may need to adjust our tests, but that should be doable.Any suggestions for how to quickly test for the available precision without
finfo? We had a number of tests that usedfinfo.eps.SwayamInSync commentedon Sep 12, 2025
We internally package this within the numpy_quaddtype, it should be as simple as
ngoldbaum commentedon Sep 12, 2025
We're aware that np.finfo doesn't know about user dtypes, it's on our list of things to work on...
dlakaplan commentedon Oct 10, 2025
OK, I finally got around to installing this on a machine under the
armplatform. I used a fresh conda install and a fresh environment, withnumpy-quaddtypeinstalled throughpip. But when I try some of the basic tests I get:I don't know if this is something specific to the machine or to how
numpy-quaddtypewas packaged. Any ideas?ngoldbaum commentedon Oct 10, 2025
I've never seem this before but IMO getting an error like this on import after installing a wheel is bu definition a bug in the quaddtype packaging. Would you mind filing an issue on the numpy-user-dtypes repo about this? It would also help to get information about your system and how you set up your Python environment so we can reproduce the issue.
dlakaplan commentedon Oct 10, 2025
OK, thanks. numpy/numpy-quaddtype#22
dlakaplan commentedon Oct 22, 2025
OK, moving on now. One possible way to implement this is to monkey-patch
np.longdoubletoQuadPrecDType(backend="sleef"). But having a callable function of the dtype would help with that. Is that something that's in the works? I don't know the tradeoffs.ngoldbaum commentedon Oct 22, 2025
Long-term, we probably would need to write a NEP to add the dtype to numpy itself. Out of curiosity, why is monkeypatching numpy needed on your end? Is there a lot of code that uses string type codes or something like that?
28 remaining items
dlakaplan commentedon Jan 20, 2026
Hi, @ngoldbaum and @SwayamInSync One issue I'm encountering now is that we store our data in
astropy.table.Tableobjects and that works fine, but it fails when we try to stack two tables:so the last operation fails with:
I don't know why this is happening here, since I can clearly create new arrays with that dtype. A workaround may be possible, but in case there was something obvious/subtle that I was missing, I thought I'd ask. Note that this is with
astropy8.0.ngoldbaum commentedon Jan 20, 2026
I'm not sure offhand.
@mhvk do you happen to have any insight about the interaction between astropy and quaddtype described in the comment above? Hopefully Marten has a bit more context about this.
mhvk commentedon Jan 20, 2026
Interesting conversation! I've been meaning to try the quaddtype for astropy's
Time(which currently uses two doubles), so nice to see the progress.Directly related to here: The error message suggests it is not related to astropy since it is just trying to create a zero-filled array with
np.zeros... (would check, but my office machine seems to old for numpy-quaddtype, I get an error on import,RuntimeError: Invalid slot with value 1031 passed in.)dlakaplan commentedon Jan 20, 2026
Hi, @mhvk Nice to hear from you. I understand your point about this not being astropy related, but something like
np.zeros((40,),dtype=QuadPrecDType)works just fine. So I don't know if somehow it's not seeing the import of that package. In my example I am creating arrays in that way to start.ngoldbaum commentedon Jan 20, 2026
Ah I missed this was just using numpy.
@dlakaplan if you can make a more minimal example that triggers this behavior it might help to figure out the issue.
dlakaplan commentedon Jan 20, 2026
Unfortunately I cannot figure out a more minimal example. That is my problem. Array creation on its own works fine, but somehow when this is done from within the table module it does not work. So I don't know if it's a subtle namespace issue or something else. If you have ideas about things to try I can do so.
ngoldbaum commentedon Jan 20, 2026
Can you at least share the full traceback in e.g. a github gist? It's not clear to me where the snippet of your traceback comes from. Astropy internals?
It might also help to put a breakpoint right above the problematic
np.zeroscall to see exactly whatdtypeis (e.g. its type). Maybe the repr is fooling us?SwayamInSync commentedon Jan 20, 2026
Ah its the issue from astropy, they are storing the dtype as a string and then passing that string to create zeros, basically they are doing something as following
They should just be storing it like a dtype object rather than string
SwayamInSync commentedon Jan 20, 2026
Here this line is the issue https://github.com/astropy/astropy/blob/c0ef822afb1fee1e40f6a980ba6b64f9c1486863/astropy/utils/metadata/utils.py#L59
Generally in numpy string parsing of dtype works, but this is a custom dtype, I am not sure whether there's a way to make custom dtype also get parsed in NumPy but TBH I don't like this method anyways
dlakaplan commentedon Jan 20, 2026
Ah, yes, I see. It sounds like @SwayamInSync identified the issue, but in case it's helpful the full traceback is:
SwayamInSync commentedon Jan 20, 2026
Hey @mhvk maybe you can raise the issue on quaddtype with some more info, The only requirement should be
numpy>=2.4because there we added an extra slot, so that might be missing if using older version.dlakaplan commentedon Jan 20, 2026
Sounds like for now I should try a work-around, but should I make an astropy issue? Or will one of you do that?
SwayamInSync commentedon Jan 20, 2026
Okay so I was checking the numpy's string parsing of dtypes and found a workaround, @dlakaplan you might need to add this line in top of your code to make that work
Basically this registers the string variant of
numpy_quaddtypeinto thesctypeDicthashmap. I will check with the team if we can expose a hook and make it work implicitly within the dtype but till then this hack will workdlakaplan commentedon Jan 20, 2026
Wow, thanks! that indeed works great.
mhvk commentedon Jan 20, 2026
Thanks all. I raised astropy/astropy#19197 for the astropy side.
Now excited to see how well this works with
Quantitytoo...