Di Sagemath kami temukan di tiket # 22799 kami
RuntimeWarning: invalid value encountered in multiply
sambil mengalikan angka numpy.float32
dengan data non-numpy; yaitu numpy seharusnya gagal melakukan perkalian ini secara diam-diam, dan memang demikian jika seseorang membangun dengan gcc, atau jika alih-alih np.float32
itu adalah np.float
atau np.float128
.
Lebih tepatnya, seseorang mendapat peringatan dari panggilan Python
type(numpy.float32('1.5')).__mul__(numpy.float32('1.5'), x)
di mana x
adalah polinomial univariat Sagemath dengan koefisien dalam tipe RealField
Sagemath. (dan hanya jenis data ini yang memicu ini).
Artinya, secara potensial, peringatan tidak berarti seperti itu dapat dikeluarkan di luar Sagemath; kami dapat mereproduksinya di OSX 11.12 dengan stok cc-nya (beberapa turunan dari clang 3.8), serta di Linux dengan clang 4.0 dan di FreeBSD 11.0 dengan clang 4.0 atau clang 3.7.
Secara potensial kami harus dapat menghasilkan cara untuk mereproduksi ini di luar Sagemath, meskipun kami memerlukan beberapa tip di mana dalam kode numpy __mul__
ini benar-benar diimplementasikan, untuk melihat fungsi apa yang diterapkan ke x ...
Kami melihat ini di numpy 1.11 dan di 1.12 juga.
gambar yang sama dengan numpy.float32('1.5').__mul__(x)
serta __add__
dan __sub__
.
Jenis kesalahan ini adalah tipikal array yang berisi nan
atau infinity
. Apa yang dikembalikan np.array(x)
?
@ eric-wieser: mengembalikan array(x, dtype=object)
, tidak ada peringatan.
Apakah np.multiply(np.float32('1.5'), x)
memberikan peringatan yang sama?
numpy.multiply(numpy.float32('1.5'), x)
memberikan peringatan yang sama.
Bagaimana dengan type(x).__rmul__(numpy.float32('1.5'), x)
?
Juga, jika Anda dapat menjalankan warnings.filterwarnings('error')
, maka Anda akan mendapatkan pelacakan tumpukan penuh
type(x).__rmul__(numpy.float32('1.5'), x)
TypeError: descriptor '__rmul__' requires a 'sage.structure.element.Element' object but received a 'numpy.float32'
x.__rmul__(numpy.float32('1.5'))
cukup.
Sepertinya saya lupa cara kerja rmul
. Maksud saya type(x).__rmul__(x, numpy.float32('1.5'))
, tapi menurut saya itu sama saja dengan x.__rmul__
, kecuali x
benar-benar aneh
Apakah ini juga gagal? np.multiply(np.array(1.5, dtype=object), x)
(kali ini dengan filterwarnings
, tolong)
type(x).__rmul__(x,numpy.float32('1.5'))
berjalan tanpa peringatan.
Dan, omong-omong, menyetel warnings.filterwarnings('error')
tidak memberi saya sesuatu yang menarik,
---------------------------------------------------------------------------
RuntimeWarning Traceback (most recent call last)
<ipython-input-50-b3ece847d318> in <module>()
sage: np.multiply(np.array(1.5, dtype=object), x)
---------------------------------------------------------------------------
RuntimeWarning Traceback (most recent call last)
<ipython-input-52-706823a0b5a2> in <module>()
----> 1 np.multiply(np.array(RealNumber('1.5'), dtype=object), x)
RuntimeWarning: invalid value encountered in multiply
Hmm, sage melakukan sesuatu yang tidak saya duga di sana. Perilaku yang sama dengan float('1.5')
, menurut saya?
Oke, jadi inilah yang menurut saya terjadi:
numpy
benar menggunakan loop objek di ufunc, yang akhirnya hanya memanggil PyNumber_Multiply
sage
, ada sesuatu yang menyetel bendera kesalahan di FPU (bug di sage?)numpy
melakukan pemeriksaan flag fpu normalnya saat keluar dari ufunc (bug dalam loop objek?), Dan menemukan kesalahan yang ditinggalkan oleh sage
sage: float(1.5).__mul__(x)
NotImplemented
sage: np.float(1.5).__mul__(x)
NotImplemented
sage: np.float32(1.5).__mul__(x)
/usr/home/dima/Sage/sage/src/bin/sage-ipython:1: RuntimeWarning: invalid value encountered in multiply
#!/usr/bin/env python
1.50000000000000*x
sage: np.float64(1.5).__mul__(x)
/usr/home/dima/Sage/sage/src/bin/sage-ipython:1: RuntimeWarning: invalid value encountered in multiply
#!/usr/bin/env python
1.50000000000000*x
Perlu dicatat bahwa np.float is float
untuk alasan kompatibilitas
mengapa np.float32(1.5).__mul__(x)
mengembalikan NotImplemented
?
Karena ia tahu bahwa ia dapat menanganinya sebagai np.multiply
dengan perulangan objek, dan kemudian mencoba lagi dengan float * x
di dalam perulangan itu. Sayangnya, pembungkus di sekitar loop itu mengambil flag FPU yang disetel oleh sage.
Jika Anda melihat lebih dekat, Anda akan menemukan bahwa x.__rmul__
masih dipanggil lebih dalam di tumpukan
sage: np.float32(1.5)*x
/usr/home/dima/Sage/sage/src/bin/sage-ipython:1: RuntimeWarning: invalid value encountered in multiply
#!/usr/bin/env python
1.50000000000000*x
sage: np.float128(1.5)*x
1.50000000000000*x
sage: np.float64(1.5)*x
/usr/home/dima/Sage/sage/src/bin/sage-ipython:1: RuntimeWarning: invalid value encountered in multiply
#!/usr/bin/env python
1.50000000000000*x
jadi sepertinya np.float128
OK, tapi
sage: np.float128(1.5).__mul__(x)
/usr/home/dima/Sage/sage/src/bin/sage-ipython:1: RuntimeWarning: invalid value encountered in multiply
#!/usr/bin/env python
1.50000000000000*x
Ini aneh. Bug kompilator, mungkin (karena kita tidak pernah melihatnya di gcc), tetapi di tempat mana?
Flag FPU untuk beberapa alasan disetel pada clang tetapi tidak dengan gcc dalam kode sage, tampaknya. Numpy yang harus disalahkan karena membuat keributan tentang hal itu, tetapi saya sangat ragu yang harus disalahkan karena mengaturnya sejak awal.
Sayangnya, numpy
tidak mengungkapkan cara apa pun untuk secara eksplisit meminta flag FPU - itu akan sangat membantu untuk membagi dua masalah dalam sage.
Saya berasumsi ini menyebabkan peringatan yang sama (perlu numpy 1,12 untuk melakukannya, saya pikir)
mul = np.vectorize(x.__rmul__)
mul(float('1.5'))
tidak persis sama, tapi hampir:
/usr/home/dima/Sage/sage/local/lib/python2.7/site-packages/numpy/lib/function_base.py:2652: RuntimeWarning: invalid value encountered in __rmul__ (vectorized)
outputs = ufunc(*inputs)
array(1.50000000000000*x, dtype=object)
Oke, bagus, ini sepertinya menunjukkan bahwa tidak ada yang spesifik dengan np.float32
atau np.float64
, ini adalah mekanisme numpy yang lebih umum untuk menghasilkan peringatan yang muncul di sini.
Saya tidak tahu bahwa penulis kompilator akan menganggapnya sebagai bug. Cara kerja peringatan adalah, ada beberapa tanda status ajaib yang terus dilacak oleh prosesor, yang secara otomatis disetel setiap kali peristiwa terkait terjadi. Numpy membersihkannya sebelum memulai penghitungan, lalu memeriksanya lagi di akhir. Jadi di suatu tempat di antara titik-titik tersebut, assembly yang dihasilkan oleh clang melakukan beberapa kalkulasi yang melibatkan NaN. Tetapi sulit untuk dilacak (karena pengaturan flag sebenarnya dilakukan sepenuhnya di perangkat keras), dan sebagian besar waktu orang tidak khawatir tentang bagaimana kode mereka memengaruhi flag fpu. (Implementasi Libm juga terkenal tidak konsisten tentang apakah mereka menyetel flag ini.) Dan hasil pastinya sangat bergantung pada asm yang dibuat, jadi tidak mengherankan jika Anda hanya melihatnya dalam konfigurasi tertentu dan bukan yang lain.
Ya, itu menegaskan kecurigaan saya, dan memberi Anda cara untuk melakukan debug. Kode ini
def check_fpu(f):
@functools.wraps(f)
def wrapped(*args, **kwargs):
excluded = list(range(len(args))) + list(kwargs.keys())
fvec = np.vectorize(f, excluded=excluded)
return fvec(*args, **kwargs)
return wrapped
Diterapkan ke fungsi python, memungkinkan Anda mengisolasi peringatan ke dalam potongan kode itu.
Maksud saya, cukup aneh bahwa hal itu terjadi sama sekali; kompiler biasanya tidak menemukan dan kemudian membuang NaN tanpa alasan.
Jika Anda mencoba melacaknya, Anda mungkin harus melihat kode di sage yang mengimplementasikan perkalian untuk polinomial tersebut - kemungkinan pengaturan bendera aneh mungkin terjadi sepanjang waktu, dan satu-satunya keterlibatan numpy adalah membuatnya terlihat .
Ada juga argumen yang cukup bagus bahwa numpy seharusnya tidak mencoba memeriksa tanda ini pada loop objek. (Atau loop integer dalam hal ini, tetapi itu rumit karena cara kami melaporkan overflow integer agak kotor dan menggunakan bendera fpu.) Itulah satu-satunya hal yang dapat saya pikirkan tentang numpy yang dapat dilakukan di sini.
check_fpu()
ada kesalahan ketik, seharusnya fvec = np.vectorize(f, excluded=exclude)
disana.
Dan, kami menggunakan python2: import functools32 as functools
.
functools.wraps
tidak membutuhkan python 3, bukan?
Saya mendapatkan kesalahan jika saya menggunakan functools python2, di setattr()
panggilan
AttributeError: 'method-wrapper' object has no attribute '__module__'
Ya, saya menduga itu adalah pustaka multi-presisi apa pun yang menerapkan aritmatika untuk koefisien dalam RealField
yang menyetel bendera FPU. Apakah pustaka yang mendasarinya dikompilasi dengan kompiler yang sama dengan numpy dalam setiap keadaan yang berbeda? Atau hanya numpy yang dibangun kembali dengan kompiler yang berbeda?
Ya, saya menduga itu adalah perpustakaan multi-presisi yang menerapkan aritmatika untuk koefisien di RealField
Itu MPFR untuk dicatat.
Kami mencoba port Sagemath untuk clang + gfortran (kebanyakan di OSX dan FreeBSD, platform di mana clang adalah kompiler utama), sehingga membangun dan menjalankannya di OSX lebih mudah dan lebih cepat (FreeBSD lebih merupakan alat untuk mendapatkan lingkungan yang serupa tanpa kerumitan OSX dan perangkat keras Apple).
Semua perbandingan yang saya laporkan di sini adalah untuk build lengkap dengan clang / clang +++ gfortran dibandingkan dengan gcc / g +++ gfortran.
pembungkusnya sepertinya memberi tahu kita bahwa x.__rmul__
menyetel flag FPU
check_fpu(x.__rmul__)(np.float32('1.5'))
mencetak peringatan, sedangkan x.__rmul__(np.float32('1.5'))
tidak.
Memang - asumsi saya adalah bahwa x.__rmul__
ditulis dengan python, dan kode sumbernya dapat dibagi dua untuk menemukan bit mana yang secara spesifik menetapkan bendera
x.__rmul__
ada di Cython, tapi tetap saja itu adalah kode kecil untuk diselidiki.
Jika ada cara sederhana untuk mengubah peringatan menjadi kesalahan, Anda akan mendapatkan traceback (Cython menghasilkan traceback untuk kesalahan tetapi tidak untuk peringatan).
@jdemeyer IMHO peringatan numpy dikeluarkan jauh kemudian di jalur kode, yaitu hasil dari pemeriksaan eksplisit bendera FPU, bukan set interupsi.
numpy memang menyediakan antarmuka untuk mengubah peringatan ini menjadi kesalahan, tetapi yang Anda dapatkan hanyalah kembali ke loop interpreter iPython utama, tanpa pelacakan balik apa pun.
@jdemeyer akankah kode Cython antara sig_on()
/ sig_off()
dari sinyalnya membuat pengecualian jika flag FPU dinaikkan? Atau tergantung benderanya?
cysignals akan memunculkan pengecualian jika SIGFPE
dimunculkan, yang mungkin terjadi jika flag FPU dinaikkan, bergantung pada konfigurasi FPU. Tetapi secara default tidak.
Peringatan serupa: RuntimeWarning: invalid value encountered in greater
adalah
berasal dari np.float64(5)>e
. Di sini e
adalah konstanta Sagemath yang menentukan basis dari logaritma natural 2.71828 ..., dan seterusnya cara mengevaluasi ini menjadi True
harus "diubah" (tentu saja, e "tahu "pendekatan numeriknya, e.n()
) untuk sebuah angka.
Perkiraan ini adalah tipe RealField
sudah disebutkan di atas (jadi mungkin peringatan ini terkait erat).
Sekali lagi, pertanyaannya adalah: apa yang dilakukan numpy
untuk mengevaluasi np.float64(5)>e
?
Atau secara ekuivalen, peringatan yang sama muncul dari np.float64(5).__gt__(e)
, jadi kita bisa mulai dari sana.
Perhatikan bahwa type(e)
adalah sage.symbolic.constants_c.E
; itu pada dasarnya beberapa (hampir) kelas tiruan
membungkus ekspresi simbolis Sagemath ( SR
).
Tidak ada peringatan dari np.float64(5).__gt__(e.n())
atau np.float64(5)>e.n()
.
Pada dasarnya hal yang sama (peringatan yang sama / tidak ada pola peringatan) terjadi jika Anda mengganti e
dengan pi
(dengan jelas pi.n()==3.1.415...
).
pi
memiliki tipe SR
, yaitu sage.symbolic.expression.Expression
.
Jawabannya sama di sini - panggilan numpy np.greater
dengan loop objek. Di tingkat bawah, itu menyebut e.__lt__(5.0)
. Tetapi sekali lagi, ia memeriksa bendera FPU sebelum dan sesudah, dan memperhatikan bahwa ada sesuatu yang salah.
Sebagian besar operator aritmatika / logika ndarray (dengan pengecualian -
dan divmod
) didelegasikan ke ufuncs. Ketika dipanggil dengan objek sage, ini akan memanggil loop O
(object) untuk ufunc ini. Loop objek ini akan melakukan loop pada array (yang dalam hal ini adalah 0d), menjalankan operator python normal pada elemen, _tetapi periksa flag FPU ketika melakukannya_.
Jadi sekali lagi, sage mengatur bendera ini. Mungkin ini adalah tanda bug, mungkin bukan.
Saya pikir ada argumen bagus di sini bahwa numpy tidak boleh memeriksa flag fpu untuk kasus ini. @njsmith , menurut Anda apakah kita harus melanjutkan dengan menghapus centang untuk tipe objek?
Faktanya, e.__lt__(5.0)
adalah ekspresi simbolis:
sage: type(e.__lt__(np.float32(5.0)))
<type 'sage.symbolic.expression.Expression'>
sage: e.__lt__(np.float32(5.0))
e < 5.0
sage: bool(e.__lt__(np.float32(5.0))) # this is how it's evaluated
True
dan dengan demikian saya benar-benar ragu bahwa itu disebut pada akhirnya, karena seseorang mendapatkan True
. Juga, check_fpu
pembungkus Anda dari atas tidak membuatnya mencetak peringatan, yaitu yang berikut ini hanya berfungsi.
sage: check_fpu(e.__lt__)(np.float32(5.0))
e < 5.0
Saya dapat menyematkan masalah kami di Sagemath ke ekstensi C tertentu menggunakan modul Python fpectl (yang agak, tetapi tidak sepenuhnya, rusak di FreeBSD). Ini sebenarnya sangat cepat setelah saya berhasil memasangnya.
IMHO fpectl sangat berguna sehingga harus diperbaiki ; bahkan mungkin digunakan dalam numpy alih-alih, atau sebagai tambahan, np.seterr()
, karena memberikan perincian yang lebih baik pada komponen yang dikompilasi.
Perbedaan antara pendekatan fpectl dan np.seterr adalah:
np.seterr
menjalankan perulangan ufunc, dan kemudian memeriksa apakah ada tanda yang disetel.
fpectl
melakukan beberapa keajaiban untuk membuatnya sehingga setiap kali terjadi operasi yang menyebabkan salah satu flag disetel, perangkat keras memunculkan interupsi, kernel mengubahnya menjadi SIGFPE yang dikirim ke proses, dan menginstal sebuah SIGFPE handler yang longjmp
s langsung keluar dari signal handler ke dalam kode penanganan error.
Beberapa kelemahan dari pendekatan fpectl
adalah: (a) ia tidak bekerja sama sekali di Windows, (b) ia rusak untuk kode yang secara internal menyebabkan salah satu dari tanda ini untuk sementara disetel dan kemudian membersihkannya (ini legal dan saya berharap ada libm yang melakukannya), (c) longjmp
sangat rapuh; pada dasarnya Anda mempertaruhkan segfault setiap kali Anda melakukannya. Ini tentu saja tidak bisa menjadi solusi umum untuk ufunc yang ditentukan pengguna secara sewenang-wenang.
Mengingat semua ini, saya tidak berpikir numpy akan beralih.
Bagaimanapun, sepertinya masalah asli telah terpecahkan, jadi tutuplah ini - silakan buka terbitan baru jika Anda ingin mengajukan kasus untuk perubahan seterr
.
Bagaimanapun, sepertinya masalah asli sudah terpecahkan
Apakah kita yakin tidak ingin menonaktifkan pemeriksaan tanda FPU untuk loop objek? Tampaknya perubahan yang cukup masuk akal untuk numpy.
@ eric-wieser: oh, itu ide yang menarik, ya. mungkin ada baiknya membuka masalah untuk itu :-). "Hal yang benar" cukup rumit - idealnya kita tidak boleh menggunakan casing khusus dtype objek (pikirkan dtype pengguna), dan loop integer juga tidak boleh menggunakannya (ini mungkin merupakan pengoptimalan nyata pada beberapa arsitektur di mana pemeriksaan / menghapus flag FPU sangat lambat), tetapi loop integer memang membutuhkan cara untuk secara eksplisit menandakan kesalahan integer, yang saat ini mereka lakukan dengan secara eksplisit mengatur flag FPU, ... Saya tidak yakin ini adalah kasus di mana mudah terjadi low -menggantung buah?
Atau apakah saya salah paham, dan orang bijak hanya mengidentifikasi masalah, dan mereka masih memerlukan perubahan besar untuk benar-benar memperbaikinya?
@ njsmith : Saya tidak mengerti mengapa Anda mengatakan itu tidak akan berfungsi di Windows. (Ini akan benar di era sebelum C99). Fungsi penanganan FPU (fenv) modern tersedia segera setelah compiler C Anda memenuhi standar C99. Selain dari fenv semua yang dibutuhkan adalah setjmp / longjmp (sekali lagi, fitur C standar).
Saya juga ingin tahu tentang libm yang menyebabkan salah satu pengecualian FE selama operasi normal.
(Kecuali jika diklasifikasikan sebagai bug).
@ dimpase : Anda juga memerlukan dukungan SIGFPE, yang tidak ditentukan di C99. (Nah, C99 mengatakan bahwa harus ada SIGFPE, tapi itu untuk divide-by-zero - itu tidak menentukan cara apa pun untuk menghubungkannya ke pengecualian floating point.) Meskipun demikian, sepertinya saya salah ingat, dan meskipun Windows tidak mendukung sinyal, MSVCRT mengemulasi SIGFPE menggunakan penanganan pengecualian terstruktur, dan menyediakan fungsi non-standar _control_fp
untuk mengaktifkannya untuk pengecualian fp tertentu, jadi dukungan Windows sebenarnya bukan penghalang. OTOH tidak terlalu penting karena longjmp
pasti tidak terjadi tanpa alasan yang sangat bagus :-)
Dan FWIW, jika libm menyebabkan pengecualian FE dan kemudian menghapusnya lagi, saya tidak dapat melihat mengapa mereka menganggapnya sebagai bug. Saya tidak yakin bahwa penerapan semacam itu ada, tetapi itu masuk akal, dan jika mereka melakukannya maka cara kita akan mengetahuinya adalah b / c seseorang memberi tahu kita bahwa numpy rusak pada platform X dan satu-satunya perbaikan adalah mengembalikan perubahan Anda menyarankan.
Bisakah Anda menjawab pertanyaan yang saya ajukan di akhir komentar saya sebelumnya?
@njsmith : jika libm (atau kode pengguna lain) perlu menyebabkan pengecualian FE dan memprosesnya, ia akan menyiapkan penangan pengecualian FE-nya sendiri, menyimpan yang sebelumnya, dan memulihkan yang sebelumnya saat keluar.
Jadi tidak masalah jika kode yang mendasarinya bermain sesuai aturan.
Mengenai dukungan MS untuk ini, mereka mengirimkan fenv.h sejak Visual C (++) 2013 atau lebih .
Ini secara khusus dimaksudkan untuk berguna dengan setjmp / longjmp (bagaimana tepatnya hal itu dilakukan di bawah tenda jangan terlalu khawatir, saya harap).
Mengenai Peringatan Waktu Proses numpy:
fpectl
adalah cara cepat untuk mencapai yang terakhir. Menggunakan alat eksternal (seperti debbuggers memungkinkan Anda untuk melengkapi kode untuk memeriksa sesuatu setelah setiap instruksi) lebih sulit, lebih lambat, dan lebih rawan kesalahan --- misalnya bukan hal yang aneh bahwa bug hanya muncul pada biner yang dioptimalkan, dan menghilang segera setelah Anda mencoba menemukannya di biner yang dapat di-debug dengan baik.Mengenai masalah ini di Sage - masih memperbaiki (semoga terbatas pada beberapa masalah di MPFR saja).
Maaf, ini berputar-putar dan saya perlu beralih ke hal lain, jadi kecuali ada sesuatu yang baru muncul pada masalah fenv / sigfpe, ini akan menjadi pesan terakhir saya tentang topik tersebut. (Saya masih tertarik jika ada yang perlu dilakukan numpy untuk bug sage).
jika libm (atau kode pengguna lain) perlu menyebabkan pengecualian FE dan memprosesnya, ia akan menyiapkan pengendali pengecualian FE-nya sendiri, menyimpan yang sebelumnya,
Apa yang Anda usulkan adalah melakukan operasi yang biasanya tidak menyebabkan penangan sinyal aktif, dan mengonfigurasi prosesor dalam mode non-standar yang menyebabkan penangan sinyal diaktifkan. Sangat masuk akal bagi kode untuk melakukan operasi ini dan mengharapkan bahwa itu tidak akan memicu penangan sinyal sama sekali.
Mengenai dukungan MS untuk ini, mereka mengirimkan fenv.h sejak Visual C (++) 2013 atau lebih.
Ini secara khusus dimaksudkan agar berguna dengan setjmp / longjmp
Saya tidak mengerti apa yang Anda bicarakan di sini. Afaict, fungsionalitas standar di fenv.h hanya berguna untuk mengimplementasikan fungsionalitas numpy-style, dan MS berpegang pada standar. Saya tidak melihat fungsi apa pun di sana yang dapat digunakan dengan setjmp / longjmp sama sekali.
kode pengguna dapat bermain cepat dan longgar dengan flag FP, maka peringatan ini paling banyak opsional.
Membersihkan bendera dengan hati-hati dengan perhitungan perantara adalah kebalikan dari bermain cepat dan lepas dengan mereka. Juga, peringatannya opsional.
cara untuk sampai ke dasar dari tempat mereka berasal sangat penting agar mereka berguna; (ditingkatkan) fpectl adalah cara cepat untuk mencapai yang terakhir.
Anda benar-benar orang pertama dalam satu dekade yang membutuhkan SIGFPE untuk men-debug masalah semacam ini, dan melihat lagi komentar sage bug, sepertinya Anda tidak benar-benar mendapatkan fpectl berfungsi? Itu tidak seharusnya menyebabkan pembuangan inti. (Sepertinya sinyal cysignals menimpa kode fpectl sehingga kode itu bahkan tidak berjalan.)
Jika ini muncul lagi, yang perlu Anda lakukan adalah membuat satu panggilan C untuk mengaktifkan SIGFPE, lalu gunakan debugger untuk mendapatkan pelacakan tumpukan. Anda tidak memerlukan build debug untuk mendapatkan pelacakan tumpukan; yang perlu Anda lakukan tidak menghapus simbol. Dan hei, sekarang kita tahu kalau-kalau ini muncul lagi.
Saya paham bahwa proses debug benar-benar membuat frustrasi, tetapi tidak membantu jika bersikeras bahwa proyek lain perlu mengubah atau memelihara infrastruktur dasar ketika Anda bahkan tidak dapat menjelaskan dengan jelas apa yang akan dicapai ini. (Saya sebenarnya tidak tahu bagaimana menurut Anda numpy mengubah sesuatu di sini bahkan akan membantu Anda menemukan bug semacam ini lebih cepat - keseluruhan gagasan longjmp
adalah menghancurkan informasi yang lebih tepat yang Anda inginkan.)
Akhirnya, ternyata itu bermuara pada bug lama dalam kompilator clang C. Pada dasarnya, dalam kisaran tertentu double
tugas seperti pada
unsigned long a;
double b;
...
a = b;
mengumpulkan FE_INVALID
(dan terkadang FE_INEXACT
); btw ini juga memengaruhi jenis data float lainnya. MPFR Hebat (MPFR harus menyalin ganda ke dalam float presisi sewenang-wenang, tentu saja) orang menyediakan solusi, memperbaiki ini untuk bijak.
Kebetulan, yang terkait bahkan lebih lama (sejak 2010, dengan selusin duplikat tertutup) clang bug 8100 mengatakan bahwa tidak ada harapan untuk menggunakan clang fenv.h
untuk menghasilkan fpectl
bekerja dengan baik saat ini . Clang tidak sepenuhnya mematuhi C99 dalam hal ini, dan benar-benar malu karenanya.
Tidak yakin apakah numpy
ingin melakukan sesuatu tentangnya; mungkin komentar bahwa RuntimeWarning
mungkin hanya karena bug kompilator (mengutip "clang bug 8100", ini adalah contoh yang cukup menonjol) mungkin berguna.
bug 8100 tidak relevan; itu untuk pragma C99 untuk menonaktifkan pengoptimalan floating point, dan tidak ada kompiler utama yang mendukungnya. numpy tampaknya (kebanyakan) tetap berfungsi :-)
Inti dari bug 8100 adalah bahwa clang tidak peduli tentang operasi FP yang dikompilasi dengan benar; meskipun pengacara mungkin tidak setuju. :-)
Oke, bug 17686 yang sudah disebutkan