我想并行化数值积分函数。我想在计算过程中使用这个函数。以前的工作应该在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;
答案 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_init
,mpirun
等)启动代码,并且必须小心执行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(...);
}