MPI策略-并行化成一个函数- MPI_Gather
MPI Strategy - parallelization into a function - MPI_Gather
我尝试用MPI并行化代码。在这段代码中,要并行化的部分位于一个函数中。我必须将顺序循环转换为MPI并行循环。
在这个MPI循环之后,我必须得到一个全局数组,我打算使用MPI_Gather来获得这个数组。
下面是代码的结构:int main() {
double *array_global;
data1 = read(file1);
data2 = read(file2);
data3 = compute_on_data(data1, data2);
write(file3,data3);
function_to_parallelize(data1, data2, data3, array_global);
}
和函数" function_to_parallelize
":
function_to_parallelize(data1, data2, data3, array_global) {
int i;
for (i = 0;i<size_loop; i++)
{
compute(data1, data2, data3, i, array_global);
}
write(file4, array_global);
}
我的第一个问题是:我可以通过在main(添加rank_mpi
和nb_process
参数)中执行MPI并行化操作吗?
int main() {
int rank_mpi, nb_process;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank_mpi);
MPI_Comm_size(MPI_COMM_WORLD, &nb_process);
double *array_global;
data1 = read(file1);
data2 = read(file2);
data3 = compute_on_data(data1, data2);
if (rank_mpi = 0) {
write(file3,data3);}
function_to_parallelize(data1, data2, data3, *array_global, rank_mpi, nb_process);
}
在" function_parallelize
"
function_to_parallelize(data1, data2, data3, array_global, rank_mpi, nb_process) {
int i;
double *gathered_array_global;
int size_block = size_loop/nb_process;
for (i = rank_mpi*size_block; i < (rank_mpi+1)*size_block; i++)
{
compute(data1, data2, data3, i, array_global);
}
MPI_Gather(gathered_array_global, array_global, 0); // Gather all array_global into gathered_array_global for root process "rank_mpi = 0"
if (rank_mpi = 0) {
write(file4, gathered_array_global);}
}
? ?我的意思是,如果我使用MPI_Gather函数,我可以有理想的结果,即所有的array_global
都放入我想在"file4
"中写入的最终数组中吗?
我只知道,传统上,MPI_Gather用于main()中收集所有子数组。如果我进入一个例程,我认为进程不能与其他进程同步,因此它们之间不能通信,对吗?
我的第二个问题是关于这种并行化所采用的策略:你认为所有进程都可以读取"file1
","file2
"而不会发生冲突吗?
对于写"data3
",我认为我只能写一个进程(rank_mpi = 0
),否则,在执行时会出现错误
感谢您的帮助和建议
如果用正确的语法编写,您的伪代码将运行。在main以外的函数中使用MPI调用没有任何问题。但我不认为它会达到你想要的效果。在function_to_parallelize
中使用MPI调用很好,但让我们仔细看看,
function_to_parallelize(data1, data2, data3, array_global, rank_mpi, nb_process) {
int i;
double *gathered_array_global;
int size_block = size_loop/nb_process;
for (i = rank_mpi*size_block; i < (rank_mpi+1)*size_block; i++)
{
compute(data1, data2, data3, i, array_global);
}
MPI_Gather(gathered_array_global, array_global, 0); // Gather all array_global into gathered_array_global for root process "rank_mpi = 0"
if (rank_mpi = 0) {
write(file4, gathered_array_global);}
}
您将问题分解为每个进程上每个array_global
的一部分将被计算。例如,假设rank_mpi
是0-3
和size_loop=40
,那么size_block=10
。这意味着array_global[0-9]
将在进程0上计算,array_global[10-19]
将在进程1上计算,以此类推。然后,当您调用MPI_Gather
时,您将需要gathered_array_global
的大小为nb_process * size_loop
来保存数据。
我认为你想要的是使更小的局部数组,只是适合计算的数据(换句话说,大小为10的数组),然后将它们传递给MPI_Gather收集到大小为40的数组(gathered_array_global)。当然,您还必须小心,以防数组的大小不能被您正在使用的进程数整除。
让所有进程同时读取文件在理论上是可以的,但是你可以很容易地通过要求大量的同时读取来破坏几乎任何文件系统。我会用广播,但这取决于你的具体情况。
最后,除非使用并行输出库,否则不能让多个进程同时写入文件。无论您使用的是什么文件系统,这都有可能造成破坏。最好做你想做的,然后从一个进程中收集和编写。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 如何在MPI中将矩阵从一个进程转移到另一个进程
- 尝试启动另一个进程并通过 MPI 加入它,但获得访问冲突
- MPI:为什么在下一个示例中使用MPI_Barrier时出现错误
- MPI一个计数器用于所有进程
- MPI,通过其中一个过程生成一个孩子
- 如何使用mpi将文件从一个进程传输到另一个进程
- 大型项目的MPI编码实践多个MPI_Finalize();或者只是一个
- MPI策略-并行化成一个函数- MPI_Gather
- 通过boost发送一个简单的boost图形对象:MPI得到错误
- 编译一个混合GNU Fortran/ c++ MPI共享库
- 从另一个MPI程序中启动MPI可执行文件