說我有n個過程:如何獲得MPI中的所有等級來發送一個值爲0,然後在所有等級上進行阻止接收?
他們做一個計算,然後發送結果排名爲0。這是我希望發生的:
等級0將等待,直到它從結果所有的隊伍,然後加起來。
我該怎麼做?另外,我想避免以下內容:
例如, 4個進程P0,P1,P2,P3,
P1 -> P0
P2 -> P0
P3 -> P0
與此同時P1已完成其計算等P1-> P0再次發生。
我希望P0只在一個週期內完成3個過程的添加,然後再爲下一個週期做3個過程。
有人可以建議一個MPI功能來做到這一點?我知道MPI_Gather,但我不知道它阻擋
我想過了這個:
#include <mpi.h>
#include <stdio.h>
int main()
{
int pross, rank,p_count = 0;
int count = 10;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&pross);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
int * num = malloc((pross-1)*sizeof(int));
if(rank !=0)
{
MPI_Send(&count,1,MPI_INT,0,1,MPI_COMM_WORLD);
}
else
{
MPI_Gather(&count, 1,MPI_INT,num, 1, MPI_INT, 0,MPI_COMM_WORLD);
for(ii = 0; ii < pross-1;ii++){printf("\n NUM %d \n",num[ii]); p_count += num[ii]; }
}
MPI_Finalize();
}
我收到提示:
*** Process received signal ***
Signal: Segmentation fault (11)
Signal code: Address not mapped (1)
Failing at address: (nil)
[ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11630)[0x7fb3e3bc3630]
[ 1] /lib/x86_64-linux-gnu/libc.so.6(+0x90925)[0x7fb3e387b925]
[ 2] /usr/lib/libopen-pal.so.13(+0x30177)[0x7fb3e3302177]
[ 3] /usr/lib/libmpi.so.12(ompi_datatype_sndrcv+0x54c)[0x7fb3e3e1e3ec]
[ 4] /usr/lib/openmpi/lib/openmpi/mca_coll_tuned.so(ompi_coll_tuned_gather_intra_basic_linear+0x143)[0x7fb3d53d9063]
[ 5] /usr/lib/libmpi.so.12(PMPI_Gather+0x1ba)[0x7fb3e3e29a3a]
[ 6] sosuks(+0xe83)[0x55ee72119e83]
[ 7] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7fb3e380b3f1]
[ 8] sosuks(+0xb5a)[0x55ee72119b5a]
*** End of error message ***
而且,我想:
#include <mpi.h>
#include <stdio.h>
int main()
{
int pross, rank,p_count = 0;
int count = 10;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&pross);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
int * num = malloc((pross-1)*sizeof(int));
if(rank !=0)
{
MPI_Send(&count,1,MPI_INT,0,1,MPI_COMM_WORLD);
}
else
{
MPI_Gather(&count, 1,MPI_INT,num, 1, MPI_INT, 0,MPI_COMM_WORLD);
for(ii = 0; ii < pross-1;ii++){printf("\n NUM %d \n",num[ii]); p_count += num[ii]; }
}
MPI_Finalize();
}
我得到錯誤的位置:
*** Process received signal ***
Signal: Segmentation fault (11)
Signal code: Address not mapped (1)
Failing at address: 0x560600000002
[ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11630)[0x7fefc8c11630]
[ 1] mdscisuks(+0xeac)[0x5606c1263eac]
[ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7fefc88593f1]
[ 3] mdscisuks(+0xb4a)[0x5606c1263b4a]
*** End of error message ***
對於第二次嘗試,這裏需要注意的是send和recv是成功的,但根由於某些原因只能從隊列中接收2條消息。看到的分段錯誤是由於在num中只有兩個元素,我不明白爲什麼只接收兩次。
我打電話的代碼
mpiexec -n 6 ./sosuks
有人能告訴我去實現我的想法更好的/正確的方法是什麼?
UPDATE:
除了回答以下,我發現我在執行錯誤上面,我想和大家分享:
#include <mpi.h>
#include <stdio.h>
int main()
{
int pross, rank,p_count = 0;
int count = 10;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&pross);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Status status;
int * num = malloc((pross-1)*sizeof(int));
if(rank !=0)
{
MPI_Send(&count,1,MPI_INT,0,1,MPI_COMM_WORLD);
}
else
{
int var,lick = 0;
for(lick = 1; lick < pross; u++)
{
int fetihs;
MPI_Recv(&fetihs,1,MPI_INT,lick,1,MPI_COMM_WORLD,&status);
var += fetihs;
}
// do things with var
}
MPI_Finalize();
}
如果將所有結果相加,那麼您可能需要'MPI_Reduce',而不是'MPI_Gather'。 – Sneftel
但是它會按照上面問題中概述的阻塞過程嗎?我試圖在所有過程達到某個特定點後才進行添加。在某種程度上,我試圖「同步」來自該步驟的所有進程的結果。 – user26763
你的描述不是很清楚,但它聽起來像你想要每一輪的障礙。是的,會有障礙(沒有合理的方法來減少)。 – Sneftel