微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 C 中使用 MPI 收集拆分的 2D 数组

如何解决在 C 中使用 MPI 收集拆分的 2D 数组

我需要将这部分很长的代码改编成 c 中的 mpi。

for (i = 0; i < total; i++) {
   sum = A[next][0][0]*B[i][0] + A[next][0][1]*B[i][1] + A[next][0][2]*B[i][2];
   next++;
   while (next < last) {
      col = column[next];
      sum += A[next][0][0]*B[col][0] + A[next][0][1]*B[col][1] + A[next][0][2]*B[col][2];
      final[col][0] += A[next][0][0]*B[i][0] + A[next][1][0]*B[i][1] + A[next][2][0]*B[i][2];
      next++;
}
final[i][0] += sum;}

而我正在考虑这样的代码

for (i = 0; i < num_threads; i++) {
   for (j = 0; j < total; j++) {
      check_thread[i][j] = false;
   }
}
part = total / num_threads;
for (i = thread_id * part; i < ((thread_id + 1) * part); i++) {
   sum = A[next][0][0]*B[i][0] + A[next][0][1]*B[i][1] + A[next][0][2]*B[i][2];
   next++;
   while (next < last) {
     col = column[next];
     sum += A[next][0][0]*B[col][0] + A[next][0][1]*B[col][1] + A[next][0][2]*B[col][2];
     if (!check_thread[thread_id][col]) {
        check_thread[thread_id][col] = true;
        temp[thread_id][col] = 0.0;
     }      
     temp[thread_id][col] += A[next][0][0]*B[i][0] + A[next][1][0]*B[i][1] + A[next][2][0]*B[i][2];
     next++;
   }
   if (!check_thread[thread_id][i]) {
      check_thread[thread_id][i] = true;
      temp[thread_id][i] = 0.0;
   }
 temp[thread_id][i] += sum;
}
*
for (i = 0; i < total; i++) {
   for (j = 0; j < num_threads; j++) {
     if (check_thread[j][i]) {
        final[i][0] += temp[j][i];
     }
   }
}

然后我需要将所有临时部分集中在一个,我在考虑 MPI_Allgather 和类似的东西,就在最后两个 for (where *) 之前:

  MPI_Allgather(temp,(part*sizeof(double)),MPI_DOUBLE,temp,sizeof(**temp),MPI_COMM_WORLD);

但是我收到一个执行错误,是否可以在同一个变量中发送和接收?如果没有,在这种情况下还有什么其他解决方案?。

解决方法

您正在使用错误的参数调用 MPI_Allgather:

 MPI_Allgather(temp,(part*sizeof(double)),MPI_DOUBLE,temp,sizeof(**temp),MPI_COMM_WORLD);

相反,你应该有 (source) :

MPI_Allgather

从所有任务中收集数据并将合并的数据分发给所有任务 任务

输入参数
sendbuf 发送缓冲区起始地址(选择)
sendcount 发送缓冲区中元素的数量(整数)
sendtype 发送缓冲区元素的数据类型(句柄)
recvcount 从任何进程接收的元素数(整数)
recvtype 接收缓冲区元素的数据类型(句柄)
comm 通讯器(手柄)

你的 sendcountrecvcount 参数都是错误的,而不是 (part*sizeof(double)) 和 sizeof(**temp) 你应该从矩阵 {{1 }} 将由所有相关进程收集。

如果该矩阵在内存中连续分配,则可以在单个调用中收集矩阵,如果它是作为指针数组创建的,则必须为矩阵的每一行调用 temp,或者改用 MPI_Allgatherv

是否可以在同一个变量中发送和接收?

是的,通过使用 In-place Option

当通信器是内部通信器时,您可以执行 就地全收集操作(输出缓冲区用作输入 缓冲)。 使用变量 MPI_IN_PLACE 作为 sendbuf 的值。 在这种情况下,将忽略 sendcount 和 sendtype。每个输入数据 假定进程在该进程将接收的区域中 它自己对接收缓冲区的贡献。具体来说,结果 对使用就地选项的 MPI_Allgather 的调用是相同的 到所有进程都执行 n 次调用

的情况

MPI_GATHER ( MPI_IN_PLACE,MPI_DATATYPE_NULL,recvbuf,recvcount,recvtype,root,comm )

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。