【问题标题】:Parellel Programming: How can I apply 'MPI_Gather' or 'MPI_Scatter' instead of 'MPI_Isend' and 'MPI_Recv'并行编程:如何应用 'MPI_Gather' 或 'MPI_Scatter' 而不是 'MPI_send' 和 'MPI_Recv'
【发布时间】:2017-10-12 10:25:07
【问题描述】:

这是我计算素数的代码,我只想在这些进程之间使用集体通信。但是,当我使用“MPI_Scatter”和“MPI_Gather”而不是 MPI_Recv 和 MPI_Isend 更改代码时出现错误。我应该为它改变什么?

这是我的原始代码:

MPI_Request req;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

if( my_rank == 0){
    printf("Input(50-1000) : ");
    fflush(stdout);
    scanf("%d",&w);
    for(i=0; i<w; i++) data[i] = i+1;
}

MPI_Bcast(&w, 1, MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(data, w, MPI_INT,0,MPI_COMM_WORLD);

if( my_rank != 0){
    x = w/(p-1);
    low = (my_rank-1)*x;
    high = low+x-1;
    for(num = data[low]; num <= data[high];num++){
        result = 0;
        t=1;
        while(num>=t){
                if(num%t==0)
                result = result +1;
            t += 1;
        }
        if(result==2) i += 1;
    }
    MPI_Isend(&i,1,MPI_INT,0,0,MPI_COMM_WORLD,&req);
}

if(my_rank == 0){
    int j = 0;
    for( j = 1; j < p; j++){
        MPI_Recv(&i,1,MPI_DOUBLE,MPI_ANY_SOURCE,0,MPI_COMM_WORLD,&status);
    printf("Process %d : There are %d prime numbers\n",status.MPI_SOURCE,i );
    }
}
MPI_Finalize();

}

输出是:

Input(50-1000) : 50
Process 1 : There are 5 prime numbers
Process 2 : There are 4 prime numbers
Process 3 : There are 2 prime numbers
Process 4 : There are 4 prime numbers

这是我更改代码的部分:

if( my_rank != 0){
        x = w/(p-1);
        low = (my_rank-1)*x;
        high = low+x-1;
        for(num = data_send[low]; num <= data[high];num++){
            result = 0;
            t=1;
            while(num>=t){
                if(num%t==0)
                    result = result +1;
                    t += 1;
                }
            if(result==2) i += 1;
     }
 MPI_Scatter(data_send,1,MPI_INT,data_recv,1,MPI_INT,0,MPI_COMM_WORLD);
    }

【问题讨论】:

  • 你遇到了什么错误
  • 它只显示 'Input(50-1000) :' 输入问题,似乎程序一直在运行而不提供结果
  • 请注意,您发送 MPI_INT 但收到 MPI_DOUBLE。你也永远不会MPI_Wait()MPI_Isend()返回的请求

标签: c parallel-processing mpi scatter


【解决方案1】:

这里是你如何使用MPI_Gather()

int * results;
if( my_rank != 0){
    x = w/(p-1);
    low = (my_rank-1)*x;
    high = low+x-1;
    for(num = data[low]; num <= data[high];num++){
        result = 0;
        t=1;
        while(num>=t){
                if(num%t==0)
                result = result +1;
            t += 1;
        }
        if(result==2) i += 1;
    }
} else {
    results = (int *)malloc(p * sizeof(int));
}

MPI_Gather(&i, 1, MPI_INT, results, 1, MPI_INT, 0, MPI_COMM_WORLD);

if(my_rank == 0){
    int j = 0;
    for( j = 1; j < p; j++){
        printf("Process %d : There are %d prime numbers\n",j, results[j]);
    }
    free(results);
}

请注意,您可以安排此算法以便也对 0 级进行计算,因此使用 p MPI 任务而不是 p-1

【讨论】:

  • 哦,我明白了!非常感谢:)
【解决方案2】:

MPI_Scatter是集体操作,需要所有等级调用。 MPI_Gather 也是如此。

这意味着:MPI_Scatter 调用应该移到代码中的 if 块之外(MPI_Gather 类似)。

你可以找到一个例子here

【讨论】:

  • 另外,基于MPI_Send()/MPI_Recv()版本,你需要MPI_Gather()而不是MPI_Scatter()
  • 顺便说一句,你可以考虑对 0 级进行一些计算,否则会浪费资源等待 MPI_Gather() 完成。
  • 你能更准确地解释一下吗?当我将 MPI_Gather 函数放在 if 块之外时,所有数据都消失了……所有进程都是 0,所有素数也是原始输入值
  • Input(50-1000) : 50 进程 0 : 有 50 个素数 进程 0 : 有 50 个素数 进程 0 : 有 50 个素数 进程 0 : 有 50 个素数 像这样...
猜你喜欢
  • 1970-01-01
  • 2019-03-18
  • 2014-04-17
  • 2013-10-24
  • 2011-11-11
  • 2015-04-22
  • 2017-10-25
  • 2012-12-01
  • 2016-09-09
相关资源
最近更新 更多