【问题标题】:Finding the process with the maximum value mpi查找具有最大值 mpi 的进程
【发布时间】:2022-10-23 22:39:03
【问题描述】:

我正在尝试使用 mpi 点对点通信在线程中找到最大值(也想添加最小值,但直到我弄清楚这一点) 我假设进程形成了一个环,从 0 开始发送到他的右边,即进程 1 我只希望具有最大值的进程打印结果,但不幸的是在某些情况下 2 进程打印出结果 谁能告诉我问题出在哪里???...

#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include <mpi.h>

int main(int argc, char **argv)
{
    int rank, size, tag = 100;
    int rightrank, leftrank;
    int v, min, max, i, tmpmax, tmpmin;
    int *data;
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Status status;
    data = (int*) malloc(size * sizeof(int));
    
    rightrank = rank + 1;
    leftrank = rank - 1;
    
    if (rank == 0) {
        leftrank = size - 1;
    }
    if (rank == size - 1) {
        rightrank = 0;
    }
    
    for (i = 0; i < size; i++) {
        data[i] = rand() % 60;
    }
    v = data[rank];
    
//v=rank*10;
    printf("{rank %d , v = %d }\n", rank, v);
    
    if (rank == 0) {
        
        MPI_Send(&v, 1, MPI_INT, rightrank, tag, MPI_COMM_WORLD);
        
        MPI_Recv(&tmpmax, 1, MPI_INT, leftrank, tag, MPI_COMM_WORLD, &status);
    }
    else {
        
        MPI_Recv(&tmpmax, 1, MPI_INT, leftrank, tag, MPI_COMM_WORLD, &status);
        max = tmpmax;
        
        if (v > max) {
            max = v;
        }
        
        MPI_Send(&max, 1, MPI_INT, rightrank, tag, MPI_COMM_WORLD);
        
    }
    
    if (v == max) {
        printf("Me process of rank %d i have max value v = %d\n ", rank, v);
    }
    
    MPI_Finalize();
    return 0;
}

输出 : as u can see rank 1 and 2 print ...

【问题讨论】:

  • 你的帖子里没有问题。编辑它以提出特定问题。如果您的代码没有按照您的意愿运行,您应该准备一个minimal reproducible example
  • 使用MPI_Reduce
  • 旁注:除了 C 代码中不需要的强制转换外,这是 C 代码,而不是 C++ 代码。使用 C++ 标签会让你看到一大堆“你为什么不使用std::vector?”可能对您没有价值的 cmets。
  • @Sneftel问题是使用点对点通信所以无论如何没有MPI_Reduce我已经尝试过MPI_Reduce并且它有效但问题只是使用发送和接收
  • @VictorEijkhout 你能解释一下吗?

标签: c ubuntu parallel-processing mpi


【解决方案1】:

无论如何,非常感谢你,我已经弄清楚了...... 我的解决方案是让进程 0 循环并检查哪个索引具有最大值,如下所示:

#include <stdlib.h>
#include<unistd.h>
#include <mpi.h>

int main(int argc,char **argv)
{
int rank,size,tag=100;
int rightrank,leftrank;
int v, min, max,i,tmpmax,tmpmin;
int* data;

MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Status status;
data=(int*)malloc(size*sizeof(int));

rightrank=rank+1;
leftrank=rank-1;

if(rank==0){
leftrank=size-1;
}
if(rank==size-1){
rightrank=0;
}

for(i=0 ; i < size ; i ++){
    data[i]=rand()%80;
}
v=data[rank];

//v=rank*10;
printf("{rank %d , v = %d }
",rank,v);

if(rank==0){

    MPI_Send(&v,1,MPI_INT,rightrank,tag,MPI_COMM_WORLD);
    MPI_Send(&v,1,MPI_INT,rightrank,tag,MPI_COMM_WORLD);
    
    MPI_Recv(&tmpmax,1,MPI_INT,leftrank,tag,MPI_COMM_WORLD,&status);
    MPI_Recv(&tmpmin,1,MPI_INT,leftrank,tag,MPI_COMM_WORLD,&status);

}
else{
MPI_Recv(&tmpmax,1,MPI_INT,leftrank,tag,MPI_COMM_WORLD,&status);
max=tmpmax;
if(v>max){
max=v;
}
MPI_Send(&max,1,MPI_INT,rightrank,tag,MPI_COMM_WORLD);
sleep(0.1);
/////cal of min
MPI_Recv(&tmpmin,1,MPI_INT,leftrank,tag,MPI_COMM_WORLD,&status);
min=tmpmin;
if(v<min){
min=v;
}
MPI_Send(&min,1,MPI_INT,rightrank,tag,MPI_COMM_WORLD);
}

if(rank==0){
for(int i = 0 ; i < size ; i ++){
    if(tmpmax==data[i]){
    printf("Me Process of rank %d i have the max value ,v = %d
",i,tmpmax);
    }
}
}

if(rank==0){
for(int i = 0 ; i < size ; i ++){
    if(tmpmin==data[i]){
    printf("Me Process of rank %d i have the min value ,v = %d
",i,tmpmin);
    }
}
}

MPI_Finalize();
    return 0;
}

【讨论】:

  • 如果所有节点上的数据数组都相同,则此方法有效。由于它填充了(伪)随机数,这表明了一个不同的问题
  • @GillesGouaillardet 有没有更好的方法来显示排名和最大值?而且这里每个进程都有自己的数据数组的私有副本,对吗??我的意思是,如果我通过进程 1 或 2 打印数组的所有元素,它们可以正确显示元素吗?
  • 我很难理解你的所作所为。请发布完整的代码,我会看看。
  • @GillesGouaillardet 我已经在答案中发布了完整的代码,谢谢
猜你喜欢
  • 2020-08-24
  • 2016-05-05
  • 2017-02-20
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
相关资源
最近更新 更多