我的程序包括一个服务器级别进程和一个客户端级别进程。客户端将一个数字(Double类型的数组)传输到服务器。
这是我的代码
//Server rank
if (rank == 0){
double buf[MAX_DATA];
MPI_Open_port(MPI_INFO_NULL, port_name);
printf("server available at %s\n", port_name);
while (1) {
MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &client);
again = 1;
while (again) {
MPI_Recv(buf, MAX_DATA, MPI_DOUBLE, 0, MPI_ANY_TAG, client, &status);
switch (status.MPI_TAG) {
case 0:
MPI_Comm_free(&client);
MPI_Close_port(port_name);
MPI_Finalize();
return 0;
case 1:
MPI_Comm_disconnect(&client);
again = 0;
break;
case 2: /* do something */
printf("case 2\n");
break;
default:
/* Unexpected message type */
MPI_Abort(MPI_COMM_WORLD, 1);
}
}
}
}
// client rank
else
{
MPI_Comm server;
double buf[MAX_DATA];
MPI_Comm_connect(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &server);
int i = 0;
while (true) {
int tag = 2; /* Action to perform */
MPI_Send(buf, MAX_DATA, MPI_DOUBLE, 0, tag, server);
}
MPI_Send(buf, 0, MPI_DOUBLE, 0, 1, server);
MPI_Comm_disconnect(&server);
}
MPI_Finalize();
但代码不起作用,当我输入命令时它被卡住了 “mpiexec -n 2 MPI_HelloWorld.exe”(创建了2个运行该程序的进程)
我修改了此来源的代码:“http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node106.htm”
答案 0 :(得分:1)
少数事情:
1)服务器需要告诉客户端它将接受通信的端口。因此,在开始接受之前需要向客户端发送消息并告诉客户端此port_name。
所以,需要这样的电话:
MPI_Send(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
客户端需要收到此消息。所以,客户首先要做的是:
MPI_Recv(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
2)由于客户端/服务器需要点对点通信(您可以拥有多个客户端,但同时只能在两个进程之间),因此我们无法使用MPI_Comm_World
(包括所有进程)在MPI_Comm_accept()
和MPI_Comm_connect()
中。要使用的正确沟通者是MPI_COMM_SELF
。
因此需要将这些调用更改为:
MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &client);
和
MPI_Comm_connect(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &server);
以下代码已在我的系统上测试并运行:
#include <stdio.h>
#include <mpi.h>
#define MAX_DATA 100
int main (int argc, char *argv[]){
int rank, size;
char port_name[MPI_MAX_PORT_NAME];
MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
//Server rank
if (rank == 0){
double buf[MAX_DATA];
MPI_Open_port(MPI_INFO_NULL, port_name);
printf("server available at %s\n", port_name);
// server tells the client about the port_name
MPI_Send(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
MPI_Comm client;
MPI_Status status;
while (1) {
MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &client);
int again = 1;
while (again) {
MPI_Recv(buf, MAX_DATA, MPI_DOUBLE, 1, MPI_ANY_TAG, client, &status);
printf("server received sth!\n");
switch (status.MPI_TAG) {
case 0:
MPI_Comm_free(&client);
MPI_Close_port(port_name);
MPI_Finalize();
return 0;
case 1:
MPI_Comm_disconnect(&client);
again = 0;
break;
case 2: /* do something */
printf("case 2\n");
break;
default:
/* Unexpected message type */
MPI_Abort(MPI_COMM_WORLD, 1);
}
}
}
} else{
MPI_Status status;
// client receives the port information from server
MPI_Recv(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
MPI_Comm server;
double buf[MAX_DATA];
MPI_Comm_connect(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &server);
int i = 0;
while (1) {
int tag = 2; /* Action to perform */
MPI_Send(buf, MAX_DATA, MPI_DOUBLE, 0, tag, server);
printf("client send somthing!\n");
sleep(1);
}
MPI_Send(buf, 0, MPI_DOUBLE, 0, 1, server);
MPI_Comm_disconnect(&server);
}
MPI_Finalize();
}