У меня есть некоторый код выборки Python MCMC с поддержкой MPI, который запускает параллельные вызовы правдоподобия для отдельных ядер. Поскольку это (обязательно - не спрашивайте) отказная выборка, мне нужно, чтобы только одна из np выборок была успешной, чтобы начать следующую итерацию, и я вполне счастливо достиг ~ np x ускорения с помощью этого метода в прошлом.
Я применил это к новой проблеме, где вероятность вызывает подпрограмму фортрана, обернутую f2py. В этом случае на каждой итерации другие процессы np-1 ждут возврата самого медленного (иногда очень медленного) результата, даже если один из этих np-1 уже является приемлемым.
Поэтому я подозреваю, что мне нужно передать сообщение всем невыигрышным (с точки зрения скорости) процессам для завершения, чтобы можно было начать следующую итерацию, и мне нужно прояснить некоторые детали лучшего способа сделать это, как показано ниже.
Код Python выглядит примерно так. Сэмплер — PyMultiNEST.
from mpi4py import MPI
world=MPI.COMM_WORLD
def myloglike(parameters,data,noise):
modelDataRealisation,status=call_fortran_sub(parameters)
if status == 0: # Model generated OK
winner=world.rank # This is the rank of the current winner
# I want to pass a message to the other still-running processes
# identifying that a successful sample has come back
won=world.bcast(winner,root=winner)
# I tried receiving the message here but the fortran_sub doesn't know
# anything about this - need to go deeper - see below
# Calculate chisq value etc.
loglike = f(data,modelDataRealisation,noise)
return loglike
Должна ли трансляция проходить через главный процесс?
Теперь сложная часть заключается в том, как получить сигнал уничтожения в коде F90. Предположительно, если код всегда прослушивается (во время цикла?), он сильно замедлится, но должен ли я в любом случае использовать что-то вроде:
call MPI_RECV(winner,1,MPI_DOUBLE_PRECISION,MPI_ANY_SOURCE,MPI_ANY_TAG&
&,MPI_COMM_WORLD,0,0)
И тогда как лучше всего убить этот процесс после получения сообщения?
Наконец, нужно ли мне что-то делать в F-коде, чтобы следующая итерация перезапустила OK/породила новые процессы?
Спасибо!