Numpy: Сбой в `np.vdot` для объекта, подобного массиву

Созданный на 10 авг. 2019  ·  6Комментарии  ·  Источник: numpy/numpy

numpy.vdot может выйти из строя, если передан объект, реализующий __array__ нестандартным способом.

Ошибка сегментации происходит в этой строке кода:
https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/multiarraymodule.c#L2245
поскольку type может быть NULL если PyArray_DescrFromType не работает.

Воспроизведение примера кода:

import numpy as np

class Foo(object):
     def __array__(self, a):
         return self

np.vdot(Foo(), Foo())

Сообщение об ошибке:

Обратная трассировка:

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000100cef88e _multiarray_umath.cpython-37m-darwin.so`array_vdot + 126
    frame #1: 0x00000001005e0994 python`PyCFunction_Call + 148
    frame #2: 0x0000000100c48dc1 _multiarray_umath.cpython-37m-darwin.so`array_implement_array_function + 305
    frame #3: 0x00000001005e11b3 python`_PyMethodDef_RawFastCallKeywords + 227
    frame #4: 0x00000001005e071c python`_PyCFunction_FastCallKeywords + 44
    frame #5: 0x00000001006b6048 python`call_function + 664
    frame #6: 0x00000001006b2a18 python`_PyEval_EvalFrameDefault + 27080
    frame #7: 0x00000001006b6e45 python`_PyEval_EvalCodeWithName + 2997
    frame #8: 0x00000001005e06d6 python`_PyFunction_FastCallKeywords + 230
    frame #9: 0x00000001006b60d9 python`call_function + 809
    frame #10: 0x00000001006b2987 python`_PyEval_EvalFrameDefault + 26935
    frame #11: 0x00000001006b6e45 python`_PyEval_EvalCodeWithName + 2997
    frame #12: 0x00000001006abfb0 python`PyEval_EvalCode + 48
    frame #13: 0x00000001006ee677 python`PyRun_InteractiveOneObjectEx + 615
    frame #14: 0x00000001006ede4e python`PyRun_InteractiveLoopFlags + 190
    frame #15: 0x00000001006edd5c python`PyRun_AnyFileExFlags + 60
    frame #16: 0x0000000100710c51 python`pymain_main + 7873
    frame #17: 0x000000010071127f python`_Py_UnixMain + 111
    frame #18: 0x00007fff5f6e63d5 libdyld.dylib`start + 1

Информация о версии Numpy / Python:

Я воспроизвел это на Mac OS X с помощью:

1.17.0 3.7.2 (default, Jan 16 2019, 11:36:28)
[Clang 10.0.0 (clang-1000.11.45.2)]

и на внутренней сборке Linux.

Первоначально об этой проблеме сообщалось как https://github.com/google/jax/issues/1162.

00 - Bug

Все 6 Комментарий

Хм, vdot проверяет, какой выходной dtype будет заранее (что, я полагаю, нормально). Однако эта функция может дать сбой и вернуть NPY_NOTYPE , поэтому она должна возвращать ошибку, когда возвращается NPY_NOTYPE . Это находится в https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/multiarraymodule.c#L2241 (и в следующей строке), ошибка, которую вы видите, является возвращением ошибки позже, но я думаю, что эта функция действительно не должна возвращать ошибку (хотя было бы неплохо добавить туда и проверку ошибок).

Хотите устроить пиар?

(Было бы неплохо проверить, есть ли еще похожие варианты использования, в которых отсутствует проверка ошибок.)

Привет,
Я новичок и хотел бы поработать над этим вопросом. Есть какие-нибудь указания, с чего начать?
Заранее спасибо.

Прочтите о нашем рабочем процессе разработки . Затем вы должны перейти к точке, где вы можете запустить python runtests.py из ветки master ( git checkout master; git clean -xfd; python runtests.py ).

Когда вы настроены, вы можете начать взлом: создать ветку, добавить неудачный тест ( numpy/core/tests/teste_multiarray.py в TestVDot было бы хорошим местом), попробуйте исправить код C из подсказки выше . Если вы застряли, не стесняйтесь обращаться за помощью, и чем больше вы сможете показать, что приложили все усилия, чтобы следовать документации и намекам, тем лучше.

Добро пожаловать, @ Soniyanayak51!

Чтобы добавить к тому, что сказал @mattip : одна информация, которая отсутствует в наших документах (я думаю), - это то, как мы работаем над проблемами. Мы не используем функцию «правопреемников» GitHub, поэтому, если из недавних комментариев / PR ясно, что кто-то активно работает над проблемой, вы можете просто погрузиться в нее.

@rgommers @mattip Я добавил проверки типов, полученных из PyArray_DescrFromType (). Я не уверен, стоит ли добавлять их и для PyArray_DESCR ().
Кроме того, что касается добавления тестов в test_multiarray.py, следует ли мне добавить test_PyArrayType и добавить тесты, тип которых равен NULL? Я не уверен, как продолжить добавление тестов.

@rgommers @mattip Я добавил проверки типов, полученных из PyArray_DescrFromType (). Я не уверен, стоит ли добавлять их и для PyArray_DESCR ().
Кроме того, что касается добавления тестов в test_multiarray.py, следует ли мне добавить test_PyArrayType и добавить тесты, тип которых равен NULL? Я не уверен, как продолжить добавление тестов.

Похоже, @mattip ответил на это частично из-за пиара (я думаю). Наверное, лучше там продолжить разговор.

мне добавить test_PyArrayType и добавить тесты, для которых тип равен NULL?

Чтобы добавить немного: принцип добавления тестов обычно заключается в тестировании только общедоступного API. Так ты бы взял

...
np.vdot(Foo(), Foo())

из описания проблемы выше и добавьте это в качестве теста. Не похоже, что нужно тестировать C API отдельно.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги