MPI并行化一个功能

时间:2012-12-16 07:46:13

标签: mpi

我想并行化数值积分函数。我想在计算过程中使用这个函数。以前的工作应该在root进程中完成。这可以在MPI中做到吗?

 double integral_count_MPI(double (*function)(double) , double beginX, double endX, int      count)
 {
    double step, result;
    int i;
    if (endX - beginX <= 0) return 0;
    step = (endX - beginX) / count;
    result = 0;

    double *input = (double*)malloc((count+1) *sizeof(double));
    for (i = 0; i <= count; i ++)
    {
       input[i] = beginX + i*step;
    }
    // Calculate and gather
 }

修改

算法:

  1 process calculation;
while:
  1 process calculation;
  integration very complex function with many processes;
  1 process calculation;
end while;
1 process calculation;

2 个答案:

答案 0 :(得分:3)

MPI提供了各种方法来构建在“幕后”使用它的库。对于初学者,您可以按需初始化MPI。 MPI-2修改了调用MPI_Init的要求,因此每个兼容的实现应该能够使用NULL的{​​{1}}参数正确初始化(因为实际的程序参数可能不适用于库) 。由于MPI只应初始化一次,因此库必须通过调用MPI_Init来检查它是否已经初始化。代码基本上如下所示:

MPI_Initialized

初始化代码还通过从C标准库调用void library_init(void) { int flag; MPI_Initialized(&flag); if (!inited) { MPI_Init(NULL, NULL); atexit(library_onexit); } } 来注册退出处理程序。在此退出处理程序中,如果尚未完成MPI库,则最终确定MPI库。如果不这样做,可能会导致atexit()终止整个MPI作业,并显示至少有一个进程退出但未完成MPI的消息:

mpiexec

这种安排允许您编写void library_onexit(void) { int flag; MPI_Finalized(&flag); if (!flag) MPI_Finalize(); } 函数,就像:

integral_count_MPI

double integral_count_MPI(...) { library_init(); ... MPI computations ... } 将在第一次调用时要求初始化MPI库。由于编写integral_count_MPI的方式,以后的调用不会导致重新初始化。此外,没有必要进行明确的终结 - 退出处理程序将非常谨慎。

请注意,您仍然需要通过MPI流程启动器(library_initmpirun等)启动代码,并且必须小心执行I / O,因为串行部分代码将在每个实例中执行。许多支持MPI的库为此提供了自己的I / O例程,它们对进程级别进行过滤,并且只允许0级执行实际的I / O.您还可以使用MPI的动态流程管理工具按需生成其他流程,但这需要您将流程管理的大部分内容抽象到执行集成的库中,这会使其非常复杂(以及代码你的主程序看起来很尴尬。)

答案 1 :(得分:2)

您可以找到MPI文档here

基本上,逻辑如下:

int main()
{
    MPI_INIT(...);
    MPI_Comm_size(...);    //get the number of processes
    MPI_Comm_rank(...);    //get my rank

    if (rank == 0)     //master process
    {
        for (i = 1; i < n; i++)
            MPI_Send(...) //Send interval data specific to i process

        double result = 0;
        for (i = 1; i < n; i++)
        {
            double part_result;

            MPI_Recv(&part_result, ...) //Receive partial results from slaves

            result += part_result;
        }

        // Print result
    }
    else               //slave process
    {
        MPI_Recv(...)  //Receive interval data from master (rank 0 process)

        double result = integral_count_MPI(...);

        MPI_Send(...)  // Send results to master
    }

    MPI_FINALIZE(...);
}