Странный вывод в MPI с использованием MPI_Comm_spawn для создания процессов

Амаэй помог мне решить проблему.

Я пытался узнать о функции MPI_Comm_spawn для создания процессов, потому что я работаю над переносом проекта с PVM на MPI. Я нашел хороший пример программы здесь. Поэтому я решил немного изменить его, чтобы родительский процесс отправлял сообщение двум дочерним процессам, а затем заставлял дочерние процессы выводить сообщение. Дело в том, что дочерний процесс с рангом 0 не получает сообщение должным образом, он просто получает его часть, а дочерний процесс с рангом 1 получает сообщение и выводит его нормально. Может кто-нибудь объяснить, почему это происходит, что я делаю не так или как я могу это исправить. Большое спасибо тем, кто может помочь!

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#define NUM_SPAWNS 2
// Based on the example from: http://mpi.deino.net/mpi_functions/MPI_Comm_spawn.html
int main( int argc, char *argv[] )
{
    int my_rank;
    int size;
    int np = NUM_SPAWNS;
    int errcodes[NUM_SPAWNS];
    MPI_Comm parentcomm, intercomm;
    char greeting[100];
    char greeting2[100];
    char greeting3[100];
    MPI_Init( &argc, &argv );
    MPI_Status stat;
    MPI_Comm_get_parent( &parentcomm );
    if (parentcomm == MPI_COMM_NULL)
    {
        /* Create 2 more processes - this example must be called spawn_example.exe for this to work. */
        MPI_Comm_spawn( "spawn_example", MPI_ARGV_NULL, np, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm, errcodes );
        MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
        MPI_Comm_size(MPI_COMM_WORLD, &size);
        // Called this Jreeting because process 0 in the new MPI_COMM_WORLD was only receiving a part of this string.
        sprintf(greeting2, "Jreeting from master1 %d of %d\n", my_rank, size);
        sprintf(greeting3, "Greeting from master2 %d of %d\n", my_rank, size);
        for(int i = 0; i<np;i++)
        {
            if(i == 0)
            {
                MPI_Send(greeting2, strlen(greeting)+1, MPI_BYTE, i,1,intercomm);
            }
            if(i == 1)
            {
                MPI_Send(greeting3, strlen(greeting)+1, MPI_BYTE, i,1,intercomm);
            }
            MPI_Recv(greeting, sizeof(greeting), MPI_BYTE, i, 1, intercomm, &stat);
            fputs (greeting, stdout);
        }
    }
    else
    {
        MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
        MPI_Comm_size(MPI_COMM_WORLD, &size);
        if(my_rank == 0)
        {
            MPI_Recv(greeting2, sizeof(greeting2), MPI_BYTE, 0, 1, parentcomm, &stat);
            std::cout << greeting2 << "\n";
        }
        if(my_rank == 1)
        {
            MPI_Recv(greeting3, sizeof(greeting3), MPI_BYTE, 0, 1, parentcomm, &stat);
            std::cout << greeting3 << "\n";
        }
        sprintf(greeting, "Hello world: processor %d of %d\n", my_rank, size);
        MPI_Send(greeting, strlen(greeting)+1, MPI_BYTE, 0,1,parentcomm);
    }
    fflush(stdout);
    MPI_Finalize();
    return 0;
}

Когда я компилирую, у меня появляются предупреждения ...:

hrognkelsi:MPI_TUTORIAL gumundureinarsson$ mpic++ spawn_example.cc -o spawn_example
spawn_example.cc: In function ‘int main(int, char**)’:
spawn_example.cc:24: warning: deprecated conversion from string constant to ‘char*’

Когда я бегу:

hrognkelsi:MPI_TUTORIAL gumundureinarsson$ mpirun spawn_example
Jre
Hello world: processor 0 of 2
Greeting from master2 0 of 1
Hello world: processor 1 of 2

Как видите, дочерний процесс выводит только Jre вместо Jreeting from master1 0 of 1, как предполагалось. Что происходит? Почему это работает для другого дочернего процесса?


person Gumeo    schedule 05.06.2012    source источник


Ответы (1)


Посмотрите на строку: MPI_Send(greeting2, strlen(greeting)+1, MPI_BYTE, i,1,intercomm);

Так что, если я не пропустил что-то, это не strlen (приветствие), просто 0. Вы определенно помещаете в буфер отправки больше, чем 1 элемент. Я думаю, вы хотите добавить туда strlen (приветствие2).

Я думаю, что происходит то, что родительский процесс отправляет усеченную строку и получает ответ от процесса 0, который заполняет «приветствие». Таким образом, на втором MPI_Send sizeof (приветствие) не равно нулю, следовательно, вы можете отправить все сообщение.

person Amaey    schedule 05.06.2012
comment
Большое спасибо! Исправлена ​​проблема! Глупая ошибка с моей стороны. Объясняет, почему пришло другое сообщение, я ценю. - person Gumeo; 05.06.2012
comment
greeting - это локальная переменная, размещенная в стеке, и изначально она содержит мусор. Вот почему strlen(greeting) возвращает ненулевое значение, и часть сообщения отправляется при первом вызове. Затем все происходит так, как вы описали. - person Hristo Iliev; 05.06.2012