Объяснение С программы wave_send: обмен конечной точки

В функции update каждая задача должна обменять конечные точки (граничные значения) с ее левым и правым соседями до обновления ее амплитуд вдоль волны.

Каждая задача указывает на npoints точек на волне. Атрибуты для этих точек запоминаются от values[1] до values[npoints], где values есть действительный массив двойной точности. Величины values[0] и values[npoints+1] будут содержать граничные значения из соседних задач.

Итак, задача, обменивающая конечные точки с ее левым соседом отправляет ее значение values[1] крайней левой точки и получает некое граничное значение в values[0]. Первое указывает индекс первой точки, управляемой этой задачей в полной (нераспределенной) волне. Задача, которая владеет точкой 1 на волне не имеет левого соседа и не будет призводить этот обмен.

if (first != 1)  
     {
     MPI_Isend(&values[1], 1, MPI_DOUBLE, left, E_RtoL, MPI_COMM_WORLD, 
               &Prequest[0]);
             
     MPI_Irecv(&values[0], 1, MPI_DOUBLE, left, E_LtoR, MPI_COMM_WORLD, 
               &Prequest[1]);
     }

Теги сообщения E_RtoL и E_LtoR предлагают направление, в котором сообщение передается (справа-налево или слева-направо). Коммуникатор MPI_COMM_WORLD. Так как этот коммуникатор является неблокирующим, то возвращается запрос Prequest[n], который будет использован для проверки статуса коммуникации.

Обмен с левым соседом сопровождается обменом с правым соседом Задача, которая владеет абсолютно последней точкой (индекс tpoints) на волне не имеет правого соседа и не будет делать этот обмен.

if (first + npoints -1 != tpoints)
     {
     MPI_Isend(&values[npoints], 1, MPI_DOUBLE, right, E_LtoR, 
               MPI_COMM_WORLD, &Prequest[2]);

     MPI_Irecv(&values[npoints+1], 1, MPI_DOUBLE, right, E_RtoL,
               MPI_COMM_WORLD, &Prequest[3]);
     }

Связи затем блокируют, поскольку последующие вычисления требуют конечных точек, которые передаются:

MPI_Waitall(4, Prequest, Pstatus);