Numpy: RuntimeWarning yang tidak berarti oleh np.float32 .__ mul__ yang dikompilasi clang

Dibuat pada 27 Apr 2017  ·  53Komentar  ·  Sumber: numpy/numpy

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.

Semua 53 komentar

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
  • Dalam 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:

  • jika Anda berpikir bahwa kode pengguna dapat bermain cepat dan longgar dengan flag FP, maka peringatan ini paling banyak opsional.
  • selain itu, mereka dapat dijaga standar, tetapi setidaknya cara untuk sampai ke dasar dari tempat asalnya sangat penting agar mereka berguna; (ditingkatkan) 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.
  • Bagaimanapun, hal RuntimeWarning harus dapat dimatikan.

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

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

perezpaya picture perezpaya  ·  4Komentar

astrofrog picture astrofrog  ·  4Komentar

toddrjen picture toddrjen  ·  4Komentar

marcocaccin picture marcocaccin  ·  4Komentar

keithbriggs picture keithbriggs  ·  3Komentar