【问题标题】:MPI program does nothing - running on linuxMPI 程序什么都不做 - 在 linux 上运行
【发布时间】:2016-03-01 05:46:43
【问题描述】:

我在 linux 上编写了这个 MPI C 程序。主机应该向从机发送任务并从从机接收数据(如果还有更多任务可以将它们交给完成的从机)。

所有任务完成后,应该打印解决方案。

它什么也没打印,我不知道为什么。它没有卡住,它只是在一秒钟后完成并且不打印任何东西。

P.S- 我尝试通过在代码中的不同位置放置 printf 来进行调试。 代码中打印某些内容的唯一位置是主部分的 MPI_Recv 之前,并且打印了几次(少于进程数)。

这是完整的代码:

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

#define NUMS_TO_CHECK 2000
#define RANGE_MIN -5
#define RANGE_MAX 5

#define PI  3.1415
#define MAX_ITER 100000

double func(double x);

int main (int argc, char *argv[])
{
    int numProcs, procId;
    int errorCode= MPI_ERR_COMM;
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
    MPI_Comm_rank(MPI_COMM_WORLD, &procId);
    MPI_Status status;
    int i;
    double recieve=0;
    int countPositives=0;
    double arr[NUMS_TO_CHECK];
    double difference= (RANGE_MAX - RANGE_MIN) / NUMS_TO_CHECK;
    int counter = NUMS_TO_CHECK-1; //from end to start...
    //Initiallizing the array.
    for(i=0; i<NUMS_TO_CHECK; i++){
        arr[i]=RANGE_MIN+i*difference;
    }
    //master
    if(procId==0){
        //Send tasks to all procs
        for(i=1; i<numProcs; i++){
            MPI_Send(&arr[counter], 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
            counter--;
        }
        do{
            MPI_Recv(&recieve, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
            if(recieve>0) 
            {
                countPositives++;
            }
            MPI_Send(&arr[counter], 1, MPI_DOUBLE, status.MPI_SOURCE, 0, MPI_COMM_WORLD);
            counter--;

        }while(counter>0);

        printf("Number of positives: %d", countPositives);
        MPI_Finalize();

    }
    //slaves
    else{
        MPI_Recv(&recieve, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        recieve=func(recieve);
        MPI_Send(&recieve, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);


    }

}

double func(double x) 
{
    int i;
    double value = x;
    int limit = rand() % 3 + 1;

    for(i = 0;  i < limit * MAX_ITER;  i++)
        value = sin(exp(sin(exp(sin(exp(value))))) - PI / 2) - 0.5;

    return value;
}

【问题讨论】:

  • 如果没有一些指示你自己做了哪些调试工作来找出问题所在,恐怕你不可能得到答案。首先放入 printf 调试语句或者可能是 assert 调用来验证代码中的假设是否真的成立。
  • 我尝试在代码的不同位置打印。代码中打印内容的唯一位置是主部分中的 MPI_Recv 之前。

标签: linux mpi


【解决方案1】:

我认为您的奴隶需要在 while 循环中读取数据。他们只做 1 次接收和 1 次发送。而大师从 2000 年开始。这可能是设计使然,所以我可能错了。

【讨论】:

  • 您的第 1 点是错误的。你不会混淆目的地/原点和标签吗?你的第2点也是错误的。订购 AFAICS 非常好(至少对于初始通信而言)。如果正确,第 3 点。这里缺少的是从 slave 的 recv+send 循环,以及传达工作结束的方法。
  • 呃。看代码已经很晚了。接得好。编辑了我的笔记。
  • 是的。就是这样。忘了循环奴隶。非常感谢!
【解决方案2】:

原则上,您的代码看起来几乎没问题。这里只缺少两件事:

  1. 最明显的一个是从属端的一种循环,接收主控的指令,然后发回他们的工作;和
  2. 不那么明显,但很重要:一种让主人知道工作何时完成的方法。它可能是一个特殊的值发送,由从站测试,并导致它们在接收时存在 recv + work + send 循环,或者您测试的不同标签。在后一种情况下,您必须使用MPI_ANY_TAG 来接收从属端的呼叫。

考虑到这一点,我相信您可以使您的代码正常工作。

【讨论】:

    猜你喜欢
    • 2014-02-16
    • 1970-01-01
    • 2014-11-30
    • 2018-12-15
    • 1970-01-01
    • 2014-01-02
    • 2021-01-18
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多