MPI последовательная основная функция - PullRequest
12 голосов
/ 31 января 2012

Это довольно простой вопрос MPI, но я не могу обойти его.У меня есть основная функция, которая вызывает другую функцию, которая использует MPI.Я хочу, чтобы основная функция выполнялась последовательно, а другая - параллельно.Мой код выглядит следующим образом:

int main (int argc, char *argv[])
{
    //some serial code goes here
    parallel_function(arg1, arg2);
    //some more serial code goes here
}

void parallel_function(int arg1, int arg2)
{
    //init MPI and do some stuff in parallel
    MPI_Init(NULL, NULL);
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    //now do some parallel stuff
    //....
    //finalize to end MPI??
    MPI_Finalize();
}

Мой код работает нормально и получает ожидаемый результат, но проблема в том, что основная функция также выполняется в отдельных процессах, поэтому последовательный код выполняется более одного раза.Я не знаю, как он работает несколько раз, потому что я еще даже не вызывал MPI_Init (если я печатаю f в главном, прежде чем я вызываю параллель_функции, я вижу несколько printf)

Как я могу остановить выполнение моей программы впараллельно после того, как я закончу?

Спасибо за любые ответы!

Ответы [ 2 ]

10 голосов
/ 31 января 2012

Посмотрите на этот ответ .

Короткая история: MPI_Init и MPI_Finalize не отмечают начало и конец параллельной обработки. Процессы MPI полностью выполняются параллельно.

9 голосов
/ 01 февраля 2012

@ suszterpatt правильно, заявив, что «процессы MPI работают параллельно полностью». Когда вы запускаете параллельную программу, используя, например, mpirun или mpiexec, запускается количество запрошенных вами процессов (с флагом -n), и каждый процесс начинает выполнение в начале main. Так в вашем примере код

int main (int argc, char *argv[])
{
    //some serial code goes here
    parallel_function(arg1, arg2);
    //some more serial code goes here
}

каждый процесс будет выполнять части //some serial code goes here и //some more serial code goes here (и, конечно, все они будут вызывать parallel_function). Нет ни одного главного процесса, который вызывает parallel_function, а затем запускает другие процессы при вызове MPI_Init.

Как правило, лучше избегать того, что вы делаете: MPI_Init должен быть одним из первых вызовов функций в вашей программе (в идеале, это должен быть первый). В частности, обратите внимание на следующее (из здесь ):

Стандарт MPI не говорит о том, что может сделать программа до MPI_INIT или после MPI_FINALIZE. В реализации MPICH вы должны делать как можно меньше. В частности, избегайте всего, что изменяет внешнее состояние программы, например открытия файлов, чтения стандартного ввода или записи в стандартный вывод.

Несоблюдение этого требования может привести к неприятным ошибкам.

Лучше переписать ваш код примерно так:

int main (int argc, char *argv[])
{

    // Initialise MPI
    MPI_Init(NULL, NULL);
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

    // Serial part: executed only by process with rank 0
    if (my_rank==0)
    {
        // Some serial code goes here
    }

    // Parallel part: executed by all processes.

    // Serial part: executed only by process with rank 0
    if (my_rank==0)
    {
        // Some more serial code goes here
    }

    // Finalize MPI
    MPI_Finalize();

    return 0;

}

Примечание : Я не программист на C, поэтому используйте приведенный выше код с осторожностью. Кроме того, main не должен всегда возвращать что-либо, особенно если определено как int main()?

...