我将其分散到MPI中的所有进程后,可以删除主级别的动态分配数组吗?

时间:2019-06-24 17:59:17

标签: c++ mpi dynamic-arrays

我尝试使用动态编写有关jacobi迭代求解器的代码     数组。我的问题是删除后删除数组是否合适     分散到所有进程。(我说的是b_local,A_local)

double *b_local;
double *A_local;
int size;
MPI_Comm_size(MPI_COMM_WORLD, &size);   
int rank;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);    
if (rank==0){
    b_local=new double[n];
    A_local=new double[n*n];
    cout<<"Enter talerance,number of iterations"<<endl;
    cin>>tol;
    cin>>max_iter;
    //Create A and scatter it to all process
    CreateMatrix(A_local);
    //Create b and scatter it to all process    
    CreateVector(b_local);

}
//data init
double *A=new double[n*n/size];
double *b=new double[n/size];
double *x_out=new double[n/size];
//brocast tol,max_iter to all processes
MPI_Bcast(&tol,1,MPI_DOUBLE,0,MPI_COMM_WORLD);//send to all processes
MPI_Bcast(&max_iter,1,MPI_INT,0,MPI_COMM_WORLD);    
//scatter vector b.Each process takes n/size
MPI_Scatter(b_local,n/size,MPI_DOUBLE,b,n/size,MPI_DOUBLE,0,MPI_COMM_WORLD);//here n_local cause we have only one column
//scatter it to all processes
MPI_Scatter(A_local,(n/size)*n,MPI_DOUBLE,A,(n/size)*n,MPI_DOUBLE,0,MPI_COMM_WORLD);//n_local*n--->number of elements in n/size rows
if (rank==0){
 delete [] b_local;
 delete [] A_local;
}

2 个答案:

答案 0 :(得分:2)

对于您发布的代码,很难说是否可以删除数组,因为缺少某些部分。

但是,一般来说,MPI_ScatterMPI_Bcast会阻止通话。这意味着仅在这些函数调用成功完成后,代码才会继续。 (这并不意味着所有进程都已完成。)MPI可能仍然可以完成一些工作,但是就您的代码而言,它已经完成了。因此,删除放置在这些函数中的数据是安全的,因为MPI在调用后将不再访问它们。

旁注:

这已在注释中指出,但我再次强调:使用智能指针来管理内存要比使用原始newdelete容易得多。您甚至可以保留C样式数组!例如:

#include <memory>

...

std::unique_ptr<double[]> b = std::make_unique<double[]>(n/size);

//at the callsites use b.get() instead of b

如果不再使用该点,则该方法允许编译器自动删除该点(及其内容)。此外,您不能忘记调用delete,而且可以正确处理异常。

或者,您可以只使用std::vector并将.data()指针传递给MPI

添加:

如果您打算一段时间使用MPI并且不喜欢使用C接口,则应考虑使用Boost.MPI之类的C ++包装库。

答案 1 :(得分:0)

MPI_Scatter是一项阻止操作,该操作将在呼叫返回后立即完成。因此,在MPI_Scatter返回之后,您可以重新使用缓冲区,尤其是删除它。相反,MPI_Iscatter是非阻塞操作。您必须等待完成,然后才能安全地重新使用缓冲区。