Я пытаюсь сделать резьбовую свертку, используя PyFFTW, чтобы вычислить большое количество
2D свертки одновременно.
(Не нужны отдельные процессы, так как GIL выпущен
для Numpy операций).
Теперь вот каноническая модель для этого:
http://code.activestate.com/recipes/577187-python-thread-pool/
(Py) FFTW очень быстрый, потому что он использует планы. Они должны быть настроены отдельно для каждого потока, чтобы избежать ошибок нарушения прав доступа, например:
class Worker(Thread):
"""Thread executing tasks from a given tasks queue"""
def __init__(self, tasks):
Thread.__init__(self)
self.tasks = tasks
self.daemon = True
# Make separate fftw plans for each thread.
flag_for_fftw='patient'
self.inputa = np.zeros(someshape, dtype='float32')
self.outputa = np.zeros(someshape_semi, dtype='complex64')
# create a forward plan.
self.fft = fftw3.Plan(self.inputa,self.outputa, direction='forward', flags=[flag_for_fftw],nthreads=1)
# Initialize the arrays for the inverse fft.
self.inputb = np.zeros(someshape_semi, dtype='complex64')
self.outputb = np.zeros(someshape, dtype='float32')
# Create the backward plan.
self.ifft = fftw3.Plan(self.inputb,self.outputb, direction='backward', flags=[flag_for_fftw],nthreads=1)
self.start()
Таким способом можно передать аргументы self.inputa
, self.outputa
, self.fft
, self.inputb
, self.outputb
, self.ifft
фактическому сверточнику в методе run класса Worker.
Это все хорошо, но мы могли бы также импортировать класс ThreadPool:
from multiprocessing.pool import ThreadPool
Но как мне определить инициализатор в ThreadPool, чтобы получить тот же результат?
Согласно документам
http://docs.python.org/library/multiprocessing.html
msgstr "каждый рабочий процесс будет вызывать инициализатор (* initargs) при запуске".
Вы можете легко проверить это в исходном коде Python.
Однако при настройке пула потоков, например, с двумя потоками:
po = ThreadPool(2,initializer=tobedetermined)
и вы запускаете его, возможно, в каком-то цикле
po.apply_async(convolver,(some_input,))
как настроить конволвер инициализатором? Как вы можете сделать это использовать отдельно
Планы FFTW в каждом потоке, без пересчета плана FFTW для каждой свертки?
Ура,
Алекс.