简体   繁体   English

MPI你好世界无法正常工作

[英]mpi hello world not working

I write simple hello-world program on Visual c++ 2010 express with MPI library and cant understand, why my code not working. 我用MPI库在Visual c ++ 2010 express上编写了简单的hello-world程序,无法理解,为什么我的代码无法正常工作。

MPI_Init( NULL, NULL );
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);

int a, b = 5;
MPI_Status st;

MPI_Send( &b, 1, MPI_INT, 0,0, MPI_COMM_WORLD );
MPI_Recv( &a, 1, MPI_INT, 0,0, MPI_COMM_WORLD, &st );

MPI_Send tells me "DEADLOCK: attempting to send a message to the local process without a prior matching receive". MPI_Send告诉我“ DEADLOCK:尝试在未事先匹配接收的情况下将消息发送到本地进程”。 If i write Recv first, program stucks there (no data, blocking receive). 如果我先写Recv,程序卡在那里(无数据,阻止接收)。 What i`m doint wrong? 我错了什么?

My studio is visual c++ 2010 express. 我的工作室是Visual C ++ 2010 Express。 MPI from HPC SDK 2008 (32 bit). HPC SDK 2008中的MPI(32位)。

You need something like this: 您需要这样的东西:

assert(size >= 2);
if (rank == 0)
    MPI_Send( &b, 1, MPI_INT, 1,0, MPI_COMM_WORLD );
if (rank == 1)
    MPI_Recv( &a, 1, MPI_INT, 0,0, MPI_COMM_WORLD, &st );

The idea of MPI is that the whole system operates in lockstep. MPI的想法是整个系统同步运行。 And sometimes you do need to be aware of which participant you are in the "world." 有时您确实需要知道您在“世界”中的参与者。 In this case, assuming you have two members (as per my assert), you need to make one of them send and the other receive. 在这种情况下,假设您有两个成员(按照我的断言),则需要使其中一个发送,另一个使接收。

Note also that I changed the "dest" parameter of the send, because 0 needs to send to 1 therefore 1 needs to receive from 0. 另请注意,我更改了send的“ dest”参数,因为0需要将发送到1,因此1需要从0接收。

You can later do it the other way around if you wish (if each needs to tell the other something), but in such a case you may find even more efficient ways to do it using "collective operations" where you can exchange (both send and receive) with all the peers. 以后,您可以根据需要以其他方式进行操作(如果每个人都需要告诉其他事情),但是在这种情况下,您可能会发现使用“集合操作”进行交换的更有效方法(都可以发送)并收到)。

In your example code, you're sending to and receiving from rank 0. If you are only running your MPI program with 1 process (which makes no sense, but we'll accept it for the sake of argument), you could make this work by using non-blocking calls instead of the blocking version. 在您的示例代码中,您是从0级别发送和接收的。如果您仅使用1个进程运行MPI程序(这没​​有任何意义,但是为了进行论证我们会接受),您可以这样做通过使用非阻塞调用而不是阻塞版本来工作。 It would change your program to look like this: 它将使您的程序看起来像这样:

MPI_Init( NULL, NULL );
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);

int a, b = 5;
MPI_Status st[2];
MPI_Request request[2];

MPI_Isend( &b, 1, MPI_INT, 0,0, MPI_COMM_WORLD, &request[0] );
MPI_Irecv( &a, 1, MPI_INT, 0,0, MPI_COMM_WORLD, &request[1] );
MPI_Waitall( request, st );

That would let both the send and the receive complete at the same time. 这样可以使发送和接收同时完成。 The reason your MPI version doesn't like your original code (which is very nice of it to tell you such a thing) is because the call to MPI_SEND could block until the matching MPI_RECV is done, which in this case wouldn't occur because it would only get called after the MPI_SEND is over, which is a circular dependency. MPI版本不喜欢原始代码的原因(很高兴告诉您这样的事情)是因为对MPI_SEND的调用可能会阻塞,直到匹配的MPI_RECV完成为止,在这种情况下不会发生,因为它只会在MPI_SEND结束后才被调用,这是循环依赖项。

In MPI, when you add an 'I' before an MPI call, it means "Immediate", as in, the call will return immediately and complete all the work later, when you call MPI_WAIT (or some version of it, like MPI_WAITALL in this example). 在MPI中,当您在MPI调用之前添加“ I”时,表示“立即”,例如,当您调用MPI_WAIT (或其某些版本,例如MPI_WAITALL时,该调用将立即返回并稍后完成所有工作。这个例子)。 So what we did here was to make the send and receive return immediately, basically just telling MPI that we intend to do a send and receive with rank 0 at some point in the future, then later (the next line), we tell MPI to go ahead and finish those calls now. 因此,我们在这里所做的就是立即使发送和接收返回,基本上只是告诉MPI我们打算在将来的某个时刻进行等级为0的发送和接收,然后稍后(下一行),我们告诉MPI:继续并立即完成这些通话。

The benefit of using the immediate version of these calls is that theoretically, MPI can do some things in the background to let the send and receive calls make progress while your application is doing something else that doesn't rely on the result of that data. 使用这些调用的即时版本的好处是,从理论上讲,MPI可以在后台执行某些操作,以使发送和接收调用在您的应用程序执行不依赖于数据结果的其他操作时取得进展。 Then, when you finish the call to MPI_WAIT* later, the data is available and you can do whatever you need to do. 然后,当您稍后完成对MPI_WAIT*的调用时,数据可用,您可以执行任何所需的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM