2016-12-17 3 views
0

Я пытаюсь распараллелить классический MPI_IssendMPI_Irecv для обмена гало с использованием потоков OpenMP и MPI_THREAD_MULTIPLE. Это означает, что каждый поток будет отправлять раздел главного буфера вправо и влево, и каждый поток отвечает за получение раздела буфера справа и слева.Распараллеливание гибридных циклов с помощью MPI_THREAD_MULTIPLE

#pragma omp parallel private(i,tid) 
    { 
    tid = omp_get_thread_num(); 
    nthreads = omp_get_num_threads(); 

// starting position for each thread 
    int sizeid = SIZE/nthreads; 
    int startid = sizeid*tid; 

    int tstep; 
    for (tstep = 0; tstep < 5; tstep++){   
     MPI_Irecv(&recvright[startid], sizeid, MPI_INT, right, tid+101, comm, request + tid); 
     MPI_Irecv(&recvleft[startid], sizeid, MPI_INT, left, tid+201, comm, request + nthreads + 1 + tid); 

     MPI_Issend(&sendleft[startid], sizeid, MPI_INT, left, tid+101, comm, request + nthreads + 2 + tid); 
     MPI_Issend(&sendright[startid], sizeid, MPI_INT, right, tid+201, comm, request + nthreads + 3 + tid); 

     MPI_Waitall(4*nthreads, request, status); 
    }  
} 

Однако я получаю ошибки на MPI_Waitall. Кто-нибудь знает, почему? Что я делаю не так?

ответ

1

Вы звоните MPI_Waitall по всем запросам ... из всех тем. Даже запросы, которые еще не открыты, или уже завершены другими потоками. Обязательно дождаться каждого запроса только один раз, в вашем случае в потоке, который вы инициируете неблокирующее сообщение.

BTW. ваша индексация запросов также неверна (перекрывается). Вместо request + nthreads + 2 + tid вы, вероятно, захотите request + nthreads * 2 + tid. Однако было бы намного чище и лучше просто создать поток локального массива MPI_Request[4] и дождаться этого, исправив также начальную проблему.

Смотрите также https://stackoverflow.com/a/17591795/620382

+0

@_Zulan Просто создать threadprivate 'MPI_Request' массив, кажется, решить эту проблему. – Manolete

Смежные вопросы