Подтвердить что ты не робот

Основная функция MPI

Это довольно простой вопрос с 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 еще (если я печатаю в main, прежде чем я вызову функцию parallel_function, я вижу несколько printf)

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

@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;

}

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