MPI зависает при Recv для определенного ввода

#c #parallel-processing #mpi

Вопрос:

Я новичок, когда дело доходит до MPI, и я понятия не имею, почему моя программа зависает.

Мои программы открывают файл и получают размер N, затем он использует N для чтения в 2D-массиве NxN. Затем я отправляю общую информацию каждому процессору, а затем разбиваю массив по горизонтали на куски и отправляю его каждому процессору.

 int size, 
int N = -1, generations = -1, sliceSize;
MPI_Status Stat;
MPI_Init(amp;argc, amp;argv);
MPI_Comm_size(MPI_COMM_WORLD, amp;size);
MPI_Comm_rank(MPI_COMM_WORLD, amp;rank);



if(rank==0){
std::fstream file;
file.open(argv[1]);

file >> N;

std::vector<std::vector<int>> grid(N, std::vector<int>(N));
sliceSize = N / size;

//read in matrix board from file
for (int i = 0; i < N;   i) {
        std::string temp;
        file >> temp;
        for (int j = 0; j < N;   j) {
            grid[i][j] = temp[j] - '0';
        }
    }
    file.close();

// send general info to each processor including 0;
int info[2];
        info[0] = N;
        info[1] = sliceSize;
        for (int i = 0; i < size; i  ) {
            MPI_Send(amp;info, 3, MPI_INT, i, 1, MPI_COMM_WORLD);
        }

//Split grid and send to each processor including 0;
/*
Examples Split
00000
00000

00000
00000
*/
for (int z = 0; z < size;   z) {
            int slice[sliceSize][N];
            for (int i = 0; i < sliceSize;   i) {
                for (int j = 0; j < N;   j) {
                    slice[i][j] = grid[i   (z * sliceSize)][j];
                }
            }
            MPI_Send(amp;(slice[0][0]), N * sliceSize, MPI_INT, z, 2, MPI_COMM_WORLD);
        }

}

//All ranks to execute this
 int localInfo[2];        // local info for initial information

    std::cout << "Here1 " << rank << std::endl;
    MPI_Recv(amp;localInfo, 4, MPI_INT, 0, 1, MPI_COMM_WORLD, amp;Stat);
    std::cout << "Here2 " << rank << std::endl;
    N = localInfo[0];
    sliceSize = localInfo[1];
    generations = localInfo[2];

    int mySlice[sliceSize][N];
    std::cout << "Here3 " << rank << std::endl;
    MPI_Recv(amp;(mySlice[0][0]), sliceSize * N, MPI_INT, 0, 2, MPI_COMM_WORLD, amp;Stat);
    std::cout << "Here4 " << rank << std::endl;

//Do stuff with mySlice

 

Я использовал операторы печати, чтобы попытаться помочь отфильтровать проблему.
Самое смешное, что он отлично работает при N = 10 или N = 20, но при любом большем размере возникает проблема.

Пример ввода:

 30
001000000000000000000000000000
101000000000000000000000000000
011000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000

 

При запуске кода с указанным выше вводом с использованием 2 процессоров с:
mpirun -oversubscribe -np 2 ./Parallel 40x40Input.txt

Мой вывод:

 Here1 1
Here2 1
Here3 1
 

Я думаю, что проблема связана со вторым вызовом MPI_Recv, но я просто не могу понять, почему.

Любая помощь будет действительно оценена.

Комментарии:

1. MPI_Send строго говоря, это блокирующий вызов, поэтому ваш первый цикл отправки вызовет взаимоблокировку в нулевом процессе. Или это может и не быть, но вы не можете на это рассчитывать. Пожалуйста, улучшите свой дизайн. Вероятно, вам следует использовать scatter. Ваш код также трудно читать, потому что отступы беспорядочные. Пожалуйста, используйте редактор, такой как emacs, который поможет вам с отступами.

2. Спасибо, я пытаюсь изменить его на scatter. Мой новый план состоит в том, чтобы прочитать матрицу как массив размером N * N размером 1D и разбросать ее, однако я немного смущен, поскольку файл открыт только с рангом 0, а сетка инициализируется только с рангом 0. как мне ее разбросать? Поскольку он не может находиться в ветке if(rank ==0).

3. После изменения ссылки на использование MPI_Scatter() я столкнулся с ошибками сегментации на некоторых процессорах при попытке запустить его с 5 процессорами.

4. Ваш первый разброс должен быть широковещательным.