Факторизация LU с помощью OpenMPI и опережающей отправки

#c #mpi #numeric

#c #mpi #числовое

Вопрос:

Я пытаюсь реализовать факторизацию LU матрицы Вандермонда с помощью OpenMPI. Таким образом, матрица разбивается на процессоры циклически, например, процессор 0 получает строки 0, 3, 6, 9 и так далее. На итерации k каждый процесс должен использовать строку k. Соответствующий процессор должен отправить его уже в конце итерации k-1 с неблокирующей трансляцией, а любой другой процессор должен получить его в начале итерации k. Что я сделал: строка 0 отправляется перед повторением k процессом 0. В начале итерации k:

 int source = k%size;
if (source != rank)
{   
     printf("Process %d waits for row %d from process %dn", rank, k, source);
     MPI_Irecv(bcast_buffer, n, MPI_DOUBLE, source, k, MPI_COMM_WORLD, amp;request);
     MPI_Wait(amp;request, amp;status);
     printf("Process %d received row %d from process %d and continuesn", rank, k, source);
}
 

И конец итерации k (l2gl является локальным или глобальным для индексов строк)

 // if current row (i) is row k 1
if((l2gl[i]==k 1) amp;amp; (l2gl[i]!=n-1))
{   
    // Safe row to broadcast buffer and send it to any other process
    for(tmp=0; tmp<n; tmp  )
    {   
        bcast_buffer[tmp] = A[i][tmp];
    }
    for(int r=0; r<size; r  )
    {
        printf("Process %d sends row %d to process %dn", rank, k 1, r);
        MPI_Isend(bcast_buffer, n, MPI_DOUBLE, r, k 1, MPI_COMM_WORLD, amp;request);
    }
}
 

В выходных данных я нахожу следующее:

 Process 3 received row 6 from Process 2 and continues
Process 2 received row 5 from Process 1 and continues
Process 2 sends row 6 to Process 0
Process 2 sends row 6 to Process 1
Process 2 sends row 6 to Process 2
Process 2 sends row 6 to Process 3
 

Означает ли это, что у меня определенно ошибка в связи или отпечатки могут быть в «неправильном» порядке из-за задержек вывода на печать или чего-то еще?
Поскольку результат факторизации неверен, должна быть ошибка либо в сообщении, либо в вычислении.
Я ценю любую помощь.

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

1. Нет глобального упорядочения выходных данных. Примечание MPI_Irecv() , за которым сразу следует, MPI_Wait() логически эквивалентно MPI_Recv() . Последнее следует предпочесть как для удобства чтения, так и для производительности. Если вы действительно хотите выполнить неблокирующую трансляцию, вы можете использовать MPI_Ibcast()

2. Я использовал MPI_Ibcast() эту проблему раньше, но ее было проще использовать MPI_Isend() из-за условия отправки. В противном случае каждый процесс должен выяснить, кто является отправителем / источником. Кроме того, я хотел использовать тег. Я думал, что должен использовать соответствующий MPI_Irecv() , поэтому я использовал его с MPI_Wait()

3. Это вполне допустимо MPI_Isend() как на одном конце, так и MPI_Recv() на другом конце.