Я в настоящее время экспериментируют с numba
и особенно vectorized
функции, поэтому я создал sum
векторизованную функцию (потому что это легко сравнить это np.sum
.Numbas параллельные векторизованные функции
import numpy as np
import numba as nb
@nb.vectorize([nb.float64(nb.float64, nb.float64)])
def numba_sum(element1, element2):
return element1 + element2
@nb.vectorize([nb.float64(nb.float64, nb.float64)], target='parallel')
def numba_sum_parallel(element1, element2):
return element1 + element2
array = np.ones(elements)
np.testing.assert_almost_equal(numba_sum.reduce(array), np.sum(array))
np.testing.assert_almost_equal(numba_sum_parallel.reduce(array), np.sum(array))
В зависимости от количества elements
параллельный код не возвращает тот же номер, что и целевой код cpu
. Я думаю, что это связано с тем, что связано с обычными проблемами с потоками (но почему? Это ошибка в Numba или что-то, что просто происходит при использовании параллельного выполнения?). Забавно, что иногда это срабатывает, иногда это не так. Иногда он терпит неудачу с elements=1000
иногда начинает сбой elements=100000
.
Например:
AssertionError:
Arrays are not almost equal to 7 decimals
ACTUAL: 93238.0
DESIRED: 100000.0
и если я запустить его снова
AssertionError:
Arrays are not almost equal to 7 decimals
ACTUAL: 83883.0
DESIRED: 100000.0
Мой вопрос сейчас: Почему я всегда хочу параллельный векторизованную функцию? Я понимаю, что целью функции vectorized
является предоставление возможностей numpy-ufunc, но я тестировал reduce
и accumulate
, и они перестают работать с некоторым (переменным) числом элементов и кто хочет ненадежную функцию?
Я использую numba 0.23.1
, numpy 1.10.1
с python 3.5.1
.
Я подозреваю, что вам повезло бы больше, если бы это было ошибкой, а не публиковать его здесь. – DavidW
Мой вопрос на самом деле не об ошибке, речь идет о том, где «параллельные» векторизованные функции будут иметь смысл, учитывая, что это может привести к таким проблемам. – MSeifert
А - Я вижу. В идеале он сохранил отдельный счетчик в каждом потоке и добавит их вместе в конце (посмотрите на OpenMP 'reduce' в качестве примера интерфейса многопоточности C/Fortran, который делает это). Если это будет сделано, ответ должен быть воспроизводимым (и правильно!). – DavidW