MPI: как заставить один процесс завершать все остальные — python → fortran

У меня есть некоторый код выборки 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/породила новые процессы?

Спасибо!


person jtlz2    schedule 10.03.2015    source источник


Ответы (1)


То, что вы пытаетесь сделать, не совсем учебник MPI, поэтому у меня нет для вас ответа из учебника. Похоже, вы не знаете, сколько времени займет «плохой» результат.

Вы спрашиваете: «Предположительно, если код всегда прослушивается (в цикле while?), он будет сильно замедляться», — но если вы используете неблокирующую отправку и получение, вы можете выполнить работу, скажем, 100 итераций, а затем протестировать для сообщения «остановить работу».

Я бы избегал MPI_Bcast здесь, так как это не совсем то, что вам нужно. Выигрывает один процесс. Затем этот процесс должен отправить сообщение «Я выиграл!» сообщение всем остальным. Да, вы выполняете n-1 двухточечных операций, что станет головной болью, когда у вас есть миллион процессов mpi.

На рабочей стороне MPI_Irecv с ANY_SOURCE будет соответствовать любым процессам "я выиграл!" сообщение. Периодически тестируйте на завершение.

person Rob Latham    schedule 11.03.2015
comment
Большое спасибо - я: Проверяю каждые несколько итераций (штраф по времени все еще лучше, чем раньше); использование MPI_Irecv (мне пришлось тщательно устанавливать теги, чтобы избежать конфликтов с другими тегами MPI); перебор этих тегов для проверки входящих сообщений; передача массива np-элементов, а не одного целого числа. Спасибо! :) - person jtlz2; 13.03.2015