-
-
Notifications
You must be signed in to change notification settings - Fork 13
FEAT: Implementing is_integer and as_integer_ratio for QuadPrecision
#221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| } | ||
| } | ||
|
|
||
| // this is thread-unsafe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ngoldbaum precisely, Sleef_snprintf here is thread-unsafe, I believe just GIL won't help here as this is C routine and GIL only protects the Python objects.
Not 100% sure so need your opinion that whether GIL would be enough or we can lock this region with pthread_mutex
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that means that it's not safe to concurrently call Sleef_snprintf simultaneously in two threads (e.g. it's not re-entrant)?
In that case, yeah, I think you need a global lock.
I'd avoid using pthreads directly because then you'd need to do something else on Windows. Instead, I'd use PyMutex on Python 3.13 and newer and PyThread_type_lock on 3.12 and older. See e.g. the use of lapack_lite_lock in numpy/linalg/umath_linalg.cpp in NumPy, which solves a similar problem with the non-reentrant lapack_lite library.
You could also switch to C++ and use a C++ standard library but then you need to be careful you don't deadlock with the GIL by making sure you release it before doing any possibly blocking calls. The built-in lock types have deadlock protection against the GIL so you don't need to go through that trouble.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also it'd be nice to add a multithreaded test for this as well. You can look at test_multithreading.py in NumPy for some patterns to use for multithreaded tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed a multithreaded test for now only for testing this. Will push the lock after the tests get done
|
It seems not to be crashing somehow @ngoldbaum can you check the |
|
Did you try running under TSan? You'll need to build python, numpy, SLEEF, and numpy-quaddtype all with the same compiler/sanitizer stack. See https://py-free-threading.github.io/thread_sanitizer/ |
|
Do we need to add this in CI? |
|
I don't think so, a one-off local test every now and then is fine. It may make sense to add TSan testing along with supporting the free-threaded build and more extensive multithreaded testing, but not until a lot of work has happened towards that. |
|
cool, so I can push the lock adding commit |
Did this on macos and running Pytest didn't give any TSan warnings for |
|
I'll push the code with the commented options for building with TSan so that in near future, anyone wants just uncomment and test |
|
Yes; stubtest does what it's supposed to do now 🎉 The errors can easily be fixed by copying these method stubs over from numpy: |
|
@ngoldbaum is this ready to merge? |
|
@jorenham can you please take a look at this error in validating static types? |
The added methods need to be decorated with |
| @@ -1,5 +1,5 @@ | |||
| from typing import Any, Literal, TypeAlias, final, overload | |||
|
|
|||
| import builtins | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the explicit import? We use bool without the builtins.bool elsewhere in the stubs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied from the NumPy's stubs, I think both are just same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in numpy it's needed because bool is shadowed by np.bool. But that shouldn't be problem here, so no need for the builtins._
|
I try to avoid looking at code on weekends - I'll look at this next week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for taking a little while to look at this. I wanted to have time to run TSan testing locally.
For what it's worth, on the free-threaded build, I see a data race inside Sleef_iunordq1 on a global value in the new multithreaded test you added. Possibly this is shibatch/sleef#560. We should probably report it upstream as a bug.
| # export CFLAGS="-fsanitize=thread -g -O0" | ||
| # export CXXFLAGS="-fsanitize=thread -g -O0" | ||
| # export LDFLAGS="-fsanitize=thread" | ||
| # python -m pip install . -vv --no-build-isolation -Csetup-args=-Db_sanitize=thread 2>&1 | tee build_log.txt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you also need to pass --no-binary :all: as well, otherwise you'll get a numpy wheel that doesn't have TSan instrumentation. I'd also suggest using a TSan build of CPython and link to https://py-free-threading.github.io/thread_sanitizer/#compiling-cpython-and-foundational-packages-with-thread-sanitizer.
A somewhat more verbose but perhaps clearer way to do this is to explicitly install all the build deps, then build quaddtype with --no-build-isolation:
# either on the cpython_sanity docker image or
# after building and installing a TSan Python build
python -m pip install meson meson-python wheel ninja
python -m pip install "numpy @ git+https://github.com/numpy/numpy" -C'setup-args=-Db_sanitize=thread'
python -m pip install . --no-build-isolation -C'setup-args=-Db_sanitize=thread'No need to pass any special arguments for pure-python dependencies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After I figured out how to compile SLEEF with TSan instrumentation, I got this race report in the new test you added:
quaddtype/tests/test_multithreading.py::test_as_integer_ratio_reconstruction ==================
WARNING: ThreadSanitizer: data race (pid=13598)
Read of size 8 at 0x00015ef30f18 by thread T14:
#0 Sleef_iunordq1 <null> (_quaddtype_main.cpython-314t-darwin.so:arm64+0xb8ffc)
#1 QuadPrecision_as_integer_ratio <null> (_quaddtype_main.cpython-314t-darwin.so:arm64+0xdb6c)
#2 method_vectorcall_NOARGS descrobject.c:448 (libpython3.14t.dylib:arm64+0xa2218)
#3 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8ae78)
#4 _PyEval_EvalFrameDefault generated_cases.c.h:1619 (libpython3.14t.dylib:arm64+0x27e560)
#5 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#6 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#7 method_vectorcall classobject.c:73 (libpython3.14t.dylib:arm64+0x8f924)
#8 context_run context.c:728 (libpython3.14t.dylib:arm64+0x2c5404)
#9 method_vectorcall_FASTCALL_KEYWORDS descrobject.c:421 (libpython3.14t.dylib:arm64+0xa2124)
#10 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8ae78)
#11 _PyEval_EvalFrameDefault generated_cases.c.h:1619 (libpython3.14t.dylib:arm64+0x27e560)
#12 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#13 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#14 method_vectorcall classobject.c:73 (libpython3.14t.dylib:arm64+0x8f924)
#15 _PyObject_Call call.c:348 (libpython3.14t.dylib:arm64+0x8b12c)
#16 PyObject_Call call.c:373 (libpython3.14t.dylib:arm64+0x8b1a0)
#17 thread_run _threadmodule.c:359 (libpython3.14t.dylib:arm64+0x41ae78)
#18 pythread_wrapper thread_pthread.h:242 (libpython3.14t.dylib:arm64+0x36aeb0)
Previous write of size 8 at 0x00015ef30f18 by thread T74:
#0 disp_iunordq1 <null> (_quaddtype_main.cpython-314t-darwin.so:arm64+0xbada8)
#1 Sleef_iunordq1 <null> (_quaddtype_main.cpython-314t-darwin.so:arm64+0xb9014)
#2 QuadPrecision_as_integer_ratio <null> (_quaddtype_main.cpython-314t-darwin.so:arm64+0xdb6c)
#3 method_vectorcall_NOARGS descrobject.c:448 (libpython3.14t.dylib:arm64+0xa2218)
#4 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8ae78)
#5 _PyEval_EvalFrameDefault generated_cases.c.h:1619 (libpython3.14t.dylib:arm64+0x27e560)
#6 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#7 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#8 method_vectorcall classobject.c:73 (libpython3.14t.dylib:arm64+0x8f924)
#9 context_run context.c:728 (libpython3.14t.dylib:arm64+0x2c5404)
#10 method_vectorcall_FASTCALL_KEYWORDS descrobject.c:421 (libpython3.14t.dylib:arm64+0xa2124)
#11 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8ae78)
#12 _PyEval_EvalFrameDefault generated_cases.c.h:1619 (libpython3.14t.dylib:arm64+0x27e560)
#13 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#14 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#15 method_vectorcall classobject.c:73 (libpython3.14t.dylib:arm64+0x8f924)
#16 _PyObject_Call call.c:348 (libpython3.14t.dylib:arm64+0x8b12c)
#17 PyObject_Call call.c:373 (libpython3.14t.dylib:arm64+0x8b1a0)
#18 thread_run _threadmodule.c:359 (libpython3.14t.dylib:arm64+0x41ae78)
#19 pythread_wrapper thread_pthread.h:242 (libpython3.14t.dylib:arm64+0x36aeb0)
Location is global 'pnt_iunordq1' at 0x00015ef30f18 (_quaddtype_main.cpython-314t-darwin.so+0x104f18)
Thread T14 (tid=223552319, running) created by main thread at:
#0 pthread_create <null> (libclang_rt.tsan_osx_dynamic.dylib:arm64e+0x2f708)
#1 do_start_joinable_thread thread_pthread.h:289 (libpython3.14t.dylib:arm64+0x369b70)
#2 PyThread_start_joinable_thread thread_pthread.h:331 (libpython3.14t.dylib:arm64+0x3699b8)
#3 do_start_new_thread _threadmodule.c:1868 (libpython3.14t.dylib:arm64+0x41aa2c)
#4 thread_PyThread_start_joinable_thread _threadmodule.c:1991 (libpython3.14t.dylib:arm64+0x4197b8)
#5 cfunction_call methodobject.c:564 (libpython3.14t.dylib:arm64+0x12d2e4)
#6 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#7 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#8 _PyEval_EvalFrameDefault generated_cases.c.h:3227 (libpython3.14t.dylib:arm64+0x28309c)
#9 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#10 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#11 method_vectorcall classobject.c:95 (libpython3.14t.dylib:arm64+0x8f9c0)
#12 _PyObject_Call call.c:348 (libpython3.14t.dylib:arm64+0x8b12c)
#13 PyObject_Call call.c:373 (libpython3.14t.dylib:arm64+0x8b1a0)
#14 _PyEval_EvalFrameDefault generated_cases.c.h:2654 (libpython3.14t.dylib:arm64+0x28128c)
#15 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#16 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#17 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#18 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#19 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#20 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#21 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#22 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#23 _PyEval_EvalFrameDefault generated_cases.c.h:3227 (libpython3.14t.dylib:arm64+0x28309c)
#24 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#25 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#26 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#27 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#28 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#29 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#30 _PyObject_Call call.c:361 (libpython3.14t.dylib:arm64+0x8b0ec)
#31 PyObject_Call call.c:373 (libpython3.14t.dylib:arm64+0x8b1a0)
#32 _PyEval_EvalFrameDefault generated_cases.c.h:2654 (libpython3.14t.dylib:arm64+0x28128c)
#33 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#34 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#35 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#36 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#37 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#38 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#39 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#40 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#41 _PyEval_EvalFrameDefault generated_cases.c.h:3227 (libpython3.14t.dylib:arm64+0x28309c)
#42 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#43 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#44 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#45 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#46 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#47 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#48 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#49 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#50 _PyEval_EvalFrameDefault generated_cases.c.h:2959 (libpython3.14t.dylib:arm64+0x282078)
#51 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#52 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#53 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#54 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#55 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#56 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#57 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#58 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#59 _PyEval_EvalFrameDefault generated_cases.c.h:2959 (libpython3.14t.dylib:arm64+0x282078)
#60 PyEval_EvalCode ceval.c:857 (libpython3.14t.dylib:arm64+0x279ed8)
#61 run_mod pythonrun.c:1459 (libpython3.14t.dylib:arm64+0x348844)
#62 _PyRun_SimpleFileObject pythonrun.c:521 (libpython3.14t.dylib:arm64+0x343f30)
#63 _PyRun_AnyFileObject pythonrun.c:81 (libpython3.14t.dylib:arm64+0x343684)
#64 pymain_run_file main.c:429 (libpython3.14t.dylib:arm64+0x384ea4)
#65 Py_RunMain main.c:775 (libpython3.14t.dylib:arm64+0x3842d0)
#66 pymain_main main.c:805 (libpython3.14t.dylib:arm64+0x38473c)
#67 Py_BytesMain main.c:829 (libpython3.14t.dylib:arm64+0x384810)
#68 main <null> (python3.14:arm64+0x10000073c)
Thread T74 (tid=223552380, running) created by main thread at:
#0 pthread_create <null> (libclang_rt.tsan_osx_dynamic.dylib:arm64e+0x2f708)
#1 do_start_joinable_thread thread_pthread.h:289 (libpython3.14t.dylib:arm64+0x369b70)
#2 PyThread_start_joinable_thread thread_pthread.h:331 (libpython3.14t.dylib:arm64+0x3699b8)
#3 do_start_new_thread _threadmodule.c:1868 (libpython3.14t.dylib:arm64+0x41aa2c)
#4 thread_PyThread_start_joinable_thread _threadmodule.c:1991 (libpython3.14t.dylib:arm64+0x4197b8)
#5 cfunction_call methodobject.c:564 (libpython3.14t.dylib:arm64+0x12d2e4)
#6 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#7 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#8 _PyEval_EvalFrameDefault generated_cases.c.h:3227 (libpython3.14t.dylib:arm64+0x28309c)
#9 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#10 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#11 method_vectorcall classobject.c:95 (libpython3.14t.dylib:arm64+0x8f9c0)
#12 _PyObject_Call call.c:348 (libpython3.14t.dylib:arm64+0x8b12c)
#13 PyObject_Call call.c:373 (libpython3.14t.dylib:arm64+0x8b1a0)
#14 _PyEval_EvalFrameDefault generated_cases.c.h:2654 (libpython3.14t.dylib:arm64+0x28128c)
#15 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#16 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#17 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#18 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#19 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#20 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#21 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#22 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#23 _PyEval_EvalFrameDefault generated_cases.c.h:3227 (libpython3.14t.dylib:arm64+0x28309c)
#24 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#25 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#26 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#27 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#28 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#29 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#30 _PyObject_Call call.c:361 (libpython3.14t.dylib:arm64+0x8b0ec)
#31 PyObject_Call call.c:373 (libpython3.14t.dylib:arm64+0x8b1a0)
#32 _PyEval_EvalFrameDefault generated_cases.c.h:2654 (libpython3.14t.dylib:arm64+0x28128c)
#33 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#34 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#35 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#36 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#37 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#38 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#39 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#40 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#41 _PyEval_EvalFrameDefault generated_cases.c.h:3227 (libpython3.14t.dylib:arm64+0x28309c)
#42 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#43 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#44 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#45 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#46 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#47 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#48 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#49 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#50 _PyEval_EvalFrameDefault generated_cases.c.h:2959 (libpython3.14t.dylib:arm64+0x282078)
#51 _PyEval_Vector ceval.c:1965 (libpython3.14t.dylib:arm64+0x27a2fc)
#52 _PyFunction_Vectorcall call.c (libpython3.14t.dylib:arm64+0x8b4b8)
#53 _PyObject_VectorcallDictTstate call.c:146 (libpython3.14t.dylib:arm64+0x8a084)
#54 _PyObject_Call_Prepend call.c:504 (libpython3.14t.dylib:arm64+0x8bac8)
#55 call_method typeobject.c:2937 (libpython3.14t.dylib:arm64+0x197e5c)
#56 slot_tp_call typeobject.c:10232 (libpython3.14t.dylib:arm64+0x197c7c)
#57 _PyObject_MakeTpCall call.c:242 (libpython3.14t.dylib:arm64+0x8a324)
#58 PyObject_Vectorcall call.c:327 (libpython3.14t.dylib:arm64+0x8af14)
#59 _PyEval_EvalFrameDefault generated_cases.c.h:2959 (libpython3.14t.dylib:arm64+0x282078)
#60 PyEval_EvalCode ceval.c:857 (libpython3.14t.dylib:arm64+0x279ed8)
#61 run_mod pythonrun.c:1459 (libpython3.14t.dylib:arm64+0x348844)
#62 _PyRun_SimpleFileObject pythonrun.c:521 (libpython3.14t.dylib:arm64+0x343f30)
#63 _PyRun_AnyFileObject pythonrun.c:81 (libpython3.14t.dylib:arm64+0x343684)
#64 pymain_run_file main.c:429 (libpython3.14t.dylib:arm64+0x384ea4)
#65 Py_RunMain main.c:775 (libpython3.14t.dylib:arm64+0x3842d0)
#66 pymain_main main.c:805 (libpython3.14t.dylib:arm64+0x38473c)
#67 Py_BytesMain main.c:829 (libpython3.14t.dylib:arm64+0x384810)
#68 main <null> (python3.14:arm64+0x10000073c)
SUMMARY: ThreadSanitizer: data race (_quaddtype_main.cpython-314t-darwin.so:arm64+0xb8ffc) in Sleef_iunordq1+0x38
==================
I think the locking that's going to be needed is probably not limited to snprintf. In this case it looks like there's global state in the iunordq1 implementation.
| PyObject *numerator = quad_to_pylong(mantissa); | ||
| if(numerator == NULL) | ||
| { | ||
| Py_DECREF(numerator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it is annoying, testing error cases catches stuff like this...
| Py_DECREF(numerator); | |
| Py_DECREF(py_exp); |
| } | ||
| PyObject *denominator = PyLong_FromLong(1); | ||
| if (denominator == NULL) { | ||
| Py_DECREF(numerator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a goto error for this since the cleanup is repeated below.
| Py_DECREF(numerator); | |
| Py_DECREF(py_exp); | |
| Py_DECREF(numerator); |
| # '-DCMAKE_C_FLAGS=-fsanitize=thread -g', | ||
| # '-DCMAKE_CXX_FLAGS=-fsanitize=thread -g', | ||
| # '-DCMAKE_EXE_LINKER_FLAGS=-fsanitize=thread', | ||
| # '-DCMAKE_SHARED_LINKER_FLAGS=-fsanitize=thread', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I poked a little at this. It looks like this doesn't get passed down into the subproject by default so this manual patching is necessary. Too bad...
Also maybe worth mentioning in the comment above that you also need to delete the sleef subproject completely for this change to have any impact unless you're starting from a fresh clone of the repo. At least that's what I had to do for this change to have any effect.
|
That's great capture, I was using the SLEEF from the subproject itself, thanks a lot @ngoldbaum Regarding SLEEF (I didn't know pytorch uses it) but in QBLAS I am also using vectorized functions. I might need to evaluate this part extensively as from the related issues and this one itself. We are on SLEEF v3.8 (LTS is 3.9, but focussed on DFT not Quad) in short optimal fixes might can take time, but the current ones are resolvable |
closes #216
I took the reference for implementing
as_integer_ratiofrom CPython's implementation