2016-02-17 2 views
3

Я в настоящее время экспериментируют с 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.

+0

Я подозреваю, что вам повезло бы больше, если бы это было ошибкой, а не публиковать его здесь. – DavidW

+1

Мой вопрос на самом деле не об ошибке, речь идет о том, где «параллельные» векторизованные функции будут иметь смысл, учитывая, что это может привести к таким проблемам. – MSeifert

+0

А - Я вижу. В идеале он сохранил отдельный счетчик в каждом потоке и добавит их вместе в конце (посмотрите на OpenMP 'reduce' в качестве примера интерфейса многопоточности C/Fortran, который делает это). Если это будет сделано, ответ должен быть воспроизводимым (и правильно!). – DavidW

ответ

0

Вы спрашиваете:

где бы «параллельно» векторизованные функции имеют смысл, учитывая, что это может привести к таким проблемам

Учитывая, что ufuncs продуцируемого numba.vectorize(target='parallel') имеют дефектные reduce() метод, речь идет что мы можем сделать с ними, что полезно?

В вашем случае ufunc делает дополнение. Полезное применение этого с target='parallel' является поэлементное сложение двух массивов:

numba_sum(array, array) 

Это действительно быстрее, чем одноядерный решение, и, кажется, не влияет на ошибки, которые калека reduce() и друзей.

Смежные вопросы