2014-10-02 23 views
0

我試圖創建一個mpi進程環,其中每個MPI進程將啓動一個pthread,並且線程將執行環,我使用pthread,因此我可以使用MPI進程來執行另一個任務。看來我不能在pthread中使用MPI_send或MPI_Recv,我沒有編譯錯誤,但我確實有運行時錯誤。在一個pthread中使用MPI_Send C

我編譯使用此命令 mpicc -lpthread threaded_ring.c

這是運行時錯誤

a.out:28372 terminated with signal 11 at PC=2aaaaaae312d SP=2aaab0771860. Backtrace: 
/usr/lib64/libpsm_infinipath.so.1(psmi_mpool_get+0xd)[0x2aaaaaae312d] 

a.out:28366 terminated with signal 11 at PC=333c00c110 SP=2aaab02d9698. Backtrace: 
/lib64/libpthread.so.0(pthread_spin_lock+0x0)[0x333c00c110] 
/usr/lib64/libpsm_infinipath.so.1(psmi_amsh_short_request+0x180)[0x2aaaaaad31b0] 
/usr/lib64/libpsm_infinipath.so.1(+0xd9f6)[0x2aaaaaad49f6] 
/usr/lib64/libpsm_infinipath.so.1(psm_mq_send+0x41)[0x2aaaaaaf5d51] 
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(psm_send_pkt+0xb1)[0x2aaaaae0af21] 
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(psm_istartmsgv+0x130)[0x2aaaaae0a010] 
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(MPIDI_CH3_iStartMsgv+0x6)[0x2aaaaaddf1e6] 
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(MPIDI_CH3_EagerContigSend+0x89)[0x2aaaaada6e39] 
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(MPID_Send+0x116)[0x2aaaaade3136] 
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(MPI_Send+0xf8)[0x2aaaaae2a408] 
./a.out[0x4022ba] 
/lib64/libpthread.so.0[0x333c0077f1] 
/lib64/libc.so.6(clone+0x6d)[0x333bce570d] 

a.out:28373 terminated with signal 11 at PC=333bf9d428 SP=2aaab0771838. Backtrace: 

a.out:28370 terminated with signal 11 at PC=2aaaaaae312d SP=2aaab0771860. Backtrace: 

這裏是我的代碼

#include <mpi.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <time.h> 

void *ring_func(void *p) 
{ 
    int token=1; 
    int world_rank; 
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 
    int world_size; 
    MPI_Comm_size(MPI_COMM_WORLD, &world_size); 
    if (world_rank==0){ 
    MPI_Send(&token, 1, MPI_INT, (world_rank + 1) % world_size, 0, 
     MPI_COMM_WORLD); 
    } 

    if (world_rank != 0) { 
    MPI_Recv(&token, 1, MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, 
      MPI_STATUS_IGNORE); 
    printf("Process %d received token %d from process %d\n", world_rank, token, 
      world_rank - 1); 
} 
pthread_exit(NULL); 
} 

    int main(int argc, char** argv) { 
    // Initialize the MPI threaded environment 

    int provided; 
    MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE , &provided); 
if (provided < MPI_THREAD_MULTIPLE) 
{ 
    printf("Error: the MPI library doesn't provide the required thread level\n"); 
     MPI_Abort(MPI_COMM_WORLD, 0); 
     } 
    pthread_t ring ; 
    pthread_create (&ring, NULL, ring_func, NULL) ; 

    MPI_Barrier(MPI_COMM_WORLD); 
    MPI_Finalize(); 
} 
+1

可能重複的[MPI + pthreads。程序停留在MPI \ _Ssend和MPI \ _Recv](http://stackoverflow.com/questions/22249429/mpipthreads-program-stuck-on-mpi-ssend-and-mpi-recv) – 2014-10-02 08:24:24

+0

我已經添加MPI_Init_thread(&argc, &argv,MPI_THREAD_MULTIPLE,&provided);但我仍然有相同的錯誤! – 2014-10-13 06:44:20

+0

在調用「MPI_Init_thread」後檢查'provided'是否等於'MPI_THREAD_MULTIPLE'。另外,你永遠不會加入線程,並且不能保證主線程在第二個線程開始之前不會成功通過障礙並調用MPI_Finalize()。 – 2014-10-13 07:24:40

回答

0

由於斯托伊奇lliev我能夠解決這個問題,問題是主線程在我的pthread之前進行了修飾,但是我在調用MPI_Finalize()之前添加了主線程等待pthread加入的pthread_join。這裏是新代碼

#include <mpi.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <time.h> 

void *ring_func(void *p) 
{ 
    int token; 
    // Receive from the lower process and send to the higher process. Take care 
    // of the special case when you are the first process to prevent deadlock. 

    int world_rank; 
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 
    int world_size; 
    MPI_Comm_size(MPI_COMM_WORLD, &world_size); 

    if (world_rank != 0) { 
    MPI_Recv(&token, 1, MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD, 
      MPI_STATUS_IGNORE); 
    printf("Process %d received token %d from process %d\n", world_rank, token, 
      world_rank - 1); 
    } else { 
// Set the token's value if you are process 
token = -1; 
    } 
MPI_Send(&token, 1, MPI_INT, (world_rank + 1) % world_size, 0, 
      MPI_COMM_WORLD); 

if (world_rank == 0) { 
// sleep(20); 
    MPI_Recv(&token, 1, MPI_INT, world_size - 1, 0, MPI_COMM_WORLD, 
      MPI_STATUS_IGNORE); 
    printf("Process %d received token %d from process %d\n", world_rank, token, 
      world_size - 1); 
    } 

pthread_exit(NULL); 
} 

int main(int argc, char** argv) { 
    // Initialize the MPI threaded environment 

    int provided; 
    MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE , &provided); 
if (provided != MPI_THREAD_MULTIPLE) 
{ 
    printf("Error: the MPI library doesn't provide the required thread level\n"); 
     MPI_Abort(MPI_COMM_WORLD, 0); 
     } 
    pthread_t ring ; 
    pthread_create (&ring, NULL, ring_func, NULL) ; 
    pthread_join(ring,NULL); 
    MPI_Barrier(MPI_COMM_WORLD); 
    MPI_Finalize(); 
}