MPI 每个rank依次往下一个rank发送消息的循环

https://www.sharcnet.ca/help/index.php/Getting_Started_with_MPI

 #include <stdio.h>
 #include <mpi.h>
 
 #define BUFMAX 81
 
 int main(int argc, char *argv[])
 {
     char outbuf[BUFMAX], inbuf[BUFMAX];
     int rank, size;
     int sendto, recvfrom;
     MPI_Status status;
 
 
     MPI_Init(&argc, &argv);
     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
     MPI_Comm_size(MPI_COMM_WORLD, &size);
 
     sprintf(outbuf, "Hello, world! from process %d of %d", rank, size);
 
     sendto = (rank + 1) % size;
     recvfrom = ((rank + size) - 1) % size;
 
     MPI_Send(outbuf, BUFMAX, MPI_CHAR, sendto, 0, MPI_COMM_WORLD);
     MPI_Recv(inbuf, BUFMAX, MPI_CHAR, recvfrom, 0, MPI_COMM_WORLD, &status);
 
     printf("[P_%d] process %d said: \"%s\"]\n", rank, recvfrom, inbuf);
 
     MPI_Finalize();
 
     return(0);
 }
上面的实现之所有没有死锁是依赖于数据传输的中间buffer,也就是写的时候直接写到buffer,不需要等到接收端的回应,代码是可以正确运行的,但是他的实现是并不是完全依赖MPI的标准,下面给出一个MPI 安全的例子


#include <stdio.h>
#include <mpi.h>
 
#define BUFMAX 81
 
int main(int argc, char *argv[])
{
    char outbuf[BUFMAX], inbuf[BUFMAX];
    int rank, size;
    int sendto, recvfrom;
    MPI_Status status;
 
 
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
 
    sprintf(outbuf, "Hello, world! from process %d of %d", rank, size);
 
    sendto = (rank + 1) % size;
    recvfrom = ((rank + size) - 1) % size;
 
    if (!(rank % 2))
    {
        MPI_Send(outbuf, BUFMAX, MPI_CHAR, sendto, 0, MPI_COMM_WORLD);
        MPI_Recv(inbuf, BUFMAX, MPI_CHAR, recvfrom, 0, MPI_COMM_WORLD, &status);
    }
    else
    {
        MPI_Recv(inbuf, BUFMAX, MPI_CHAR, recvfrom, 0, MPI_COMM_WORLD, &status);
        MPI_Send(outbuf, BUFMAX, MPI_CHAR, sendto, 0, MPI_COMM_WORLD);
    }
 
    printf("[P_%d] process %d said: \"%s\"]\n", rank, recvfrom, inbuf);
 
    MPI_Finalize();
 
    return(0);
}





这个例子和上面的最大的不同就是根据rank分成两组,这两组的接收和发送的顺序是刚好相反的,这样如果没有buffer,一样可以正确的得到结果,因此是安全的。


 

好的,我可以为您提供一个在并行环境下的mpi矩阵向量乘法的代码样例: ``` #include <stdio.h> #include <mpi.h> int main(int argc, char *argv[]) { int rank, size; double a[N][N], x[N], y[N]; int i, j; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { // initialize matrix A and vector x for (i = 0; i < N; i++) { x[i] = ...; // initialize vector x for (j = 0; j < N; j++) { a[i][j] = ...; // initialize matrix A } } } // scatter x and matrix A across all processes MPI_Scatter(x, N/size, MPI_DOUBLE, x, N/size, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Scatter(a, N*N/size, MPI_DOUBLE, a, N*N/size, MPI_DOUBLE, 0, MPI_COMM_WORLD); // compute local dot products for (i = 0; i < N/size; i++) { y[i] = 0.0; for (j = 0; j < N; j++) { y[i] += a[i][j] * x[j]; } } // gather results onto process 0 MPI_Gather(y, N/size, MPI_DOUBLE, y, N/size, MPI_DOUBLE, 0, MPI_COMM_WORLD); if (rank == 0) { // compute final vector y for (i = 0; i < N; i++) { printf("%f ", y[i]); } printf("\n"); } MPI_Finalize(); return 0; } ``` 这段代码使用了 MPI(Message Passing Interface)来实现矩阵向量乘法。它首先在进程 0 中初始化矩阵 A 和向量 x,然后将它们分散到所有进程中。接下来,每个进程计算矩阵的一部分与向量的乘积,并将结果收集到进程 0 中。最终,进程 0 计算向量 y 的最终结果并输出。在这个算法中,每个进程只需要计算矩阵与向量的一部分,从而实现了并行计算,并将计算结果进行了聚合,从而得到了整个向量 y 的计算结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值