0

我尝试使用 MPI 来解决蒙特卡洛问题,如果我们生成 x 数量的兰特。num 介于 0 和 1 之间,然后将 n 长度的数字发送到每个处理器。我正在使用 scatter 函数,但我的代码运行不正确,它编译但它不要求输入。我不明白 MPI 如何在没有循环的情况下自行循环,有人可以解释一下,我的代码有什么问题吗?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "mpi.h"

main(int argc, char* argv[]) {
int         my_rank;       /* rank of process      */
int         p;             /* number of processes  */
int         source;        /* rank of sender       */
int         dest;          /* rank of receiver     */
int         tag = 0;       /* tag for messages     */
char        message[100];  /* storage for message  */
MPI_Status  status;        /* return status for    */
double *total_xr, *p_xr, total_size_xr, p_size_xr;  /* receive              */

/* Start up MPI */
MPI_Init(&argc, &argv);

/* Find out process rank  */
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

/* Find out number of processes */
MPI_Comm_size(MPI_COMM_WORLD, &p);

double temp;
int i, partial_sum, x, total_sum, ratio_p, area;
total_size_xr = 0;
partial_sum = 0;
if(my_rank == 0){
    while(total_size_xr <= 0){
        printf("How many random numbers should each process get?: ");
        scanf("%f", &p_size_xr);
    }
    total_size_xr = p*p_size_xr;
    total_xr = malloc(total_size_xr*sizeof(double));

    //xr generator will generate numbers between 1 and 0
    srand(time(NULL));
    for(i=0; i<total_size_xr; i++)
    {
        temp = 2.0 * rand()/(RAND_MAX+1.0) -1.0;
        //this will make sure if any number computer stays in the boundry of 0 and 1, doesn't go over into the negative
        while(temp < 0.0)
        {
            temp = 2.0 * rand()/(RAND_MAX+1.0) -1.0;
        }
        //array set to total random numbers generated to be scatter into processors
        total_xr[i] = temp;
    }

}
else{
//this will be the buffer for the processors to hold their own numbers to add
p_xr = malloc(p_size_xr*sizeof(double));
printf("\n\narray set\n\n");
//scatter xr into processors
MPI_Scatter(total_xr, total_size_xr, MPI_DOUBLE, p_xr, p_size_xr, MPI_DOUBLE, 0, MPI_COMM_WORLD);
//while in processor the partial sum will be caluclated by using xr and the formula sqrt(1-x*x)
for(i=0; i<p_size_xr; i++)
{
    x = p_xr[i];
    temp = sqrt(1 - (x*x));
    partial_sum = partial_sum + temp;
}
//}


//we will send the partial sums to master processor which is processor 0 and add them and place 
//the result in total_sum
MPI_Reduce(&partial_sum, &total_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

//once we have all of the sums we need to multiply the total sum and multiply it with 1/N
//N being the number of processors, the area should contain the value of pi.
ratio_p = 1/p;
area = total_sum*ratio_p;

printf("\n\nThe area under the curve of f(x) = sqrt(1-x*x), between 0 and 1 is, %f\n\n", area);

/* Shut down MPI */
MPI_Finalize();
} /* main */
4

1 回答 1

1

一般来说,依靠 STDIN/STDOUT 来编写 MPI 程序是不好的。MPI 实现可能会将排名 0 放在某个节点上,而不是您正在启动作业的节点。在这种情况下,您必须担心正确转发。虽然这在大多数情况下都有效,但通常不是一个好主意。

更好的方法是让您的用户输入位于应用程序可以读取的文件中或通过命令行变量。那些将更加便携。

我不确定 MPI 本身没有循环的循环是什么意思。如果您仍然需要那里的答案,也许您可​​以澄清该评论。

于 2013-07-24T13:57:28.970 回答