我尝试使用动态编写有关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;
}
答案 0 :(得分:2)
对于您发布的代码,很难说是否可以删除数组,因为缺少某些部分。
但是,一般来说,MPI_Scatter
和MPI_Bcast
会阻止通话。这意味着仅在这些函数调用成功完成后,代码才会继续。 (这并不意味着所有进程都已完成。)MPI
可能仍然可以完成一些工作,但是就您的代码而言,它已经完成了。因此,删除放置在这些函数中的数据是安全的,因为MPI
在调用后将不再访问它们。
旁注:
这已在注释中指出,但我再次强调:使用智能指针来管理内存要比使用原始new
和delete
容易得多。您甚至可以保留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
是非阻塞操作。您必须等待完成,然后才能安全地重新使用缓冲区。