【问题标题】:MPI Strategy - parallelization into a function - MPI_GatherMPI 策略 - 并行化为函数 - MPI_Gather
【发布时间】:2014-09-24 22:56:37
【问题描述】:

我尝试使用 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 中执行 MPI 并行化(添加 rank_mpinb_process 参数):

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),否则执行时会出错

感谢您的帮助和建议

【问题讨论】:

  • 如果你想做 array_global 的 MPI_Gather 的唯一原因是把它写出来,你可能想看看 MPI-IO。这可能也有助于编写数据3。

标签: c++ c arrays parallel-processing mpi


【解决方案1】:

如果以正确的语法编写,您的伪代码将运行。在 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_mpi0-3size_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)。当然,您还必须小心,以防数组的大小不能完全被您使用的进程数整除。

理论上,让所有进程同时从文件中读取是可以的,但是您可以通过请求大量同时读取来轻松破坏几乎所有文件系统。我会使用广播,但这取决于您的具体情况。

最后,除非使用并行输出库,否则不能有多个进程同时写入文件。无论您使用什么文件系统,它都有可能破坏事物。最好按照你的想法做,然后收集然后从一个过程中写出来。

【讨论】:

  • 感谢您的解释,现在我知道我可以在函数中使用 MPI_Gather,这将用于收集我的所有数组。我认为,鉴于我们进入一个函数,这是不可能的(实际上,没有真正的论点)。对于 I/O,这是我在不同 MPI 论坛上看到的:读取所有进程都可以,但我必须小心写入。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 2020-10-26
  • 2021-05-20
  • 2014-01-22
相关资源
最近更新 更多