MPI 程序什么都不做 - 运行 在 linux
MPI program does nothing - running on linux
我在 linux 上编写了这个 MPI C 程序。 master 应该向 slaves 发送任务并从 slaves 接收数据(如果有更多的任务将它们交给完成的 slaves)。
所有任务完成后,应该打印一个解决方案。
它什么都不打印,我不明白为什么。它没有卡住,它只是在一秒钟后完成并且不打印任何东西。
P.S-
我尝试通过在代码的不同位置放置 printf 来进行调试。
代码中唯一打印东西的地方是在 master 部分的 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;
}
我认为你的奴隶需要在一个 while 循环中读取数据。他们只进行 1 次接收和 1 次发送。而 master 从 2000 开始。这可能是设计使然,所以我可能是错的。
原则上,你的代码看起来差不多。这里只缺少两件事:
- 最明显的一个是从属端的某种循环,从主控端接收他们的指令,然后将他们的工作发回;和
- 不太明显但很重要:一种让主人知道工作何时完成的方法。它可能是一个特殊的值发送,由奴隶测试,并导致他们在接收时存在 recv + work + send 循环,或者您测试的不同标签。在后一种情况下,您必须使用
MPI_ANY_TAG
作为从属端的接收呼叫。
考虑到这一点,我相信您可以使您的代码正常工作。
我在 linux 上编写了这个 MPI C 程序。 master 应该向 slaves 发送任务并从 slaves 接收数据(如果有更多的任务将它们交给完成的 slaves)。
所有任务完成后,应该打印一个解决方案。
它什么都不打印,我不明白为什么。它没有卡住,它只是在一秒钟后完成并且不打印任何东西。
P.S- 我尝试通过在代码的不同位置放置 printf 来进行调试。 代码中唯一打印东西的地方是在 master 部分的 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;
}
我认为你的奴隶需要在一个 while 循环中读取数据。他们只进行 1 次接收和 1 次发送。而 master 从 2000 开始。这可能是设计使然,所以我可能是错的。
原则上,你的代码看起来差不多。这里只缺少两件事:
- 最明显的一个是从属端的某种循环,从主控端接收他们的指令,然后将他们的工作发回;和
- 不太明显但很重要:一种让主人知道工作何时完成的方法。它可能是一个特殊的值发送,由奴隶测试,并导致他们在接收时存在 recv + work + send 循环,或者您测试的不同标签。在后一种情况下,您必须使用
MPI_ANY_TAG
作为从属端的接收呼叫。
考虑到这一点,我相信您可以使您的代码正常工作。