使用MPI的客户端/服务器应用程序

client/server application using MPI

本文关键字:服务器 应用程序 客户端 MPI 使用      更新时间:2023-10-16

我有两个问题;第一个是:

我将使用msmpi,我所说的"只有mpi"是指我们不能使用套接字,我的应用程序是关于可扩展的分布式数据结构;最初,我们让一个服务器包含一个大小可变的文件(大小可以通过插入来增加,也可以通过删除来减少),当文件的大小超过一定限制时,文件将被拆分,一半保留在第一个服务器中,另一半将移动到新的服务器,依此类推…客户端需要始终收到他想要检索的数据的地址,这样他就应该有一个文件拆分操作的图像。最后,我希望我能说得更清楚。

第二个是:

我试着用msmpi或mpich2编译简单的客户端/服务器应用程序(代码源如下),但它不起作用,并给我错误消息"mpi_open_port()中的致命错误和堆栈的其他错误",所以我在ubunto 11.10上安装了open mpi,并尝试运行与服务器端相同的示例,它给了我一个端口名,但在客户端,它给我错误消息:

[user-Compaq-610:03833] [[39604,1],0] ORTE_ERROR_LOG: Not found in file ../../../../../../ompi/mca/dpm/orte/dpm_orte.c at line 155
[user-Compaq-610:3833] *** An error occurred in MPI_Comm_connect
[user-Compaq-610:3833] *** on communicator MPI_COMM_WORLD
[user-Compaq-610:3833] *** MPI_ERR_INTERN: internal error
[user-Compaq-610:3833] *** MPI_ERRORS_ARE_FATAL (your MPI job will now abort)
--------------------------------------------------------------------------
mpirun has exited due to process rank 0 with PID 3833 on
node toufik-Compaq-610 exiting without calling "finalize". This may
have caused other processes in the application to be
terminated by signals sent by mpirun (as reported here).

所以我很困惑这个问题是什么,我花了一段时间试图解决它,如果有人能帮我的话,我会非常高兴的,并提前感谢你。

源代码在这里:

/* the server side */
#include <stdio.h>
#include <mpi.h>
main(int argc, char **argv)
{
    int my_id;
    char port_name[MPI_MAX_PORT_NAME];
    MPI_Comm newcomm;
    int passed_num;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
    passed_num = 111;
    if (my_id == 0)
    {
    MPI_Open_port(MPI_INFO_NULL, port_name);
    printf("%snn", port_name); fflush(stdout);
    } /* endif */
    MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &newcomm); 
    if (my_id == 0)
    {
    MPI_Send(&passed_num, 1, MPI_INT, 0, 0, newcomm);
    printf("after sending passed_num %dn", passed_num); fflush(stdout);
    MPI_Close_port(port_name);
    } /* endif */
    MPI_Finalize();
    exit(0);
} /* end main() */

在客户端:

#include <stdio.h>
#include <mpi.h>
int main(int argc, char **argv)
{
    int passed_num;
    int my_id;
    MPI_Comm newcomm;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
    MPI_Comm_connect(argv[1], MPI_INFO_NULL, 0, MPI_COMM_WORLD, &newcomm); 
    if (my_id == 0)
    {
    MPI_Status status;
    MPI_Recv(&passed_num, 1, MPI_INT, 0, 0, newcomm, &status);
    printf("after receiving passed_num %dn", passed_num); fflush(stdout);
    } /* endif */
    MPI_Finalize();
    return 0;   
    //exit(0);
} /* end main() */

您究竟是如何运行应用程序的?提供的客户端和服务器代码似乎是相同的。

通常,所有MPI进程的代码都是相同的,程序根据秩来决定执行什么,如代码段if (my_id == 0) { ... }中所示。该应用程序使用mpiexec执行。例如,mpiexec -n 2 ./application将在一个MPI_COMM_WORLD通信器中运行两个列为12的MPI进程。进程究竟在哪里执行(在同一个节点上还是在不同的节点上)取决于配置。

不过,您应该使用MPI_Open_port创建端口,并将其传递给MPI_Comm_connect。以下是如何使用这些函数的示例:MPI_Comm_connect

此外,对于MPI_Recv,必须有相应的MPI_Send。否则接收过程将永远等待。