2011-10-23 55 views
1

我現在正在通過一些基本的MPI示例來自我介紹,以刷新我的記憶(使用Pacheco的書作爲指南),但是我遇到了一個我不太明白的問題。爲了證明屬性緩存,我寫了下面的程序:MPI中的屬性緩存

#include <stdio.h> 
#include <mpi.h> 

int main(int argc, char *argv[]) { 
    int rank, size; 
    int key; 
    int *value; 
    void* extra_arg; /* unused */ 

    /* Broadcast value for sync */ 
    int x; 

    MPI_Init(&argc,&argv); 
    MPI_Comm_rank(MPI_COMM_WORLD,&rank); 
    MPI_Comm_size(MPI_COMM_WORLD,&size); 
    MPI_Keyval_create(MPI_DUP_FN, MPI_NULL_DELETE_FN, 
     &key, extra_arg); 

    if (rank==0) { 
     *value = 42; 
     MPI_Attr_put(MPI_COMM_WORLD, key, value); 
     x=17; 
     MPI_Bcast(&x,1,MPI_INT,0,MPI_COMM_WORLD); 
    } else { 
     MPI_Bcast(&x,1,MPI_INT,0,MPI_COMM_WORLD); 
     int* newval; 
     int flag; 
     MPI_Attr_get(MPI_COMM_WORLD,key,&newval,&flag); 
     printf("Value = %d \n", *newval); 
    } 
    MPI_Finalize(); 
    return 0; 
} 

(廣播是隻是爲了防止MPI_Attr_get從放之前存在的)

這一點,如果我正確地做這件事,應該導致所有進程但排名爲0的打印「值= 42 \ n」。我能得到什麼,但是,如果我做「的mpirun -np 2 ./a.out」,是

[exp:27936] *** Process received signal *** 
[exp:27936] Signal: Segmentation fault (11) 
[exp:27936] Signal code: Invalid permissions (2) 
[exp:27936] Failing at address: 0xb763aff4 
[exp:27936] [ 0] [0xf57fe40c] 
[exp:27936] [ 1] ./a.out(main+0x74) [0x80488e8] 
[exp:27936] [ 2] /lib/libc.so.6(__libc_start_main+0xdc) [0xb74fbe9c] 
[exp:27936] [ 3] ./a.out [0x80487c1] 
[exp:27936] *** End of error message *** 
-------------------------------------------------------------------------- 
mpirun noticed that process rank 0 with PID 27936 on node exp exited on signal 11 (Segmentation fault).-------------------------------------------------------------------------- 

我不明白的是爲什麼這是段錯誤!無論我在main的頂部還是在else內部聲明「int newval」,都會發生同樣的錯誤,並且只有在MPI_Attr_get運行時纔會發生:將此註釋掉,並使用newval做其他操作。

想法?

+0

因爲我記憶中的阻塞是粗略的,我只是嘗試用同步發送/接收替換Bcast,並得到了相同的結果。 – ajdecon

回答

2

的段錯誤是因爲一個C的東西,而不是MPI的事情 - 你需要的newval是一個整數,而不是指向一個:

#include <stdio.h> 
#include <mpi.h> 

int main(int argc, char *argv[]) { 
    int rank, size; 
    int key; 
    void* extra_arg; /* unused */ 

    /* Broadcast value for sync */ 
    int x; 

    MPI_Init(&argc,&argv); 
    MPI_Comm_rank(MPI_COMM_WORLD,&rank); 
    MPI_Comm_size(MPI_COMM_WORLD,&size); 
    MPI_Keyval_create(MPI_DUP_FN, MPI_NULL_DELETE_FN, 
     &key, NULL); 

    if (rank==0) { 
     int value = 42; 
     MPI_Attr_put(MPI_COMM_WORLD, key, &value); 
     x=17; 
     MPI_Bcast(&x,1,MPI_INT,0,MPI_COMM_WORLD); 
    } else { 
     MPI_Bcast(&x,1,MPI_INT,0,MPI_COMM_WORLD); 
     int newval; 
     int flag; 
     MPI_Attr_get(MPI_COMM_WORLD,key,&newval,&flag); 
     if (flag) 
      printf("Value = %d \n", newval); 
    } 
    MPI_Finalize(); 
    return 0; 
} 

我認爲這仍然是你想要的行爲不;我不確定該屬性是否廣播到與通信器相關的所有進程。 (另請注意,MPI_Attr_get/put從MPI2開始已棄用,並由MPI_Comm_get/set_attr()取代)。