首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用MPI屏障导致致命错误

使用MPI屏障导致致命错误
EN

Stack Overflow用户
提问于 2018-06-03 03:43:05
回答 1查看 1.3K关注 0票数 1

我得到了一个奇怪的行为,我的简单MPI程序。我花了一些时间自己寻找答案,但我做不到。我在这里提出了一些问题,比如OpenMPI MPI_Barrier problemsMPI_SEND stops working after MPI_BARRIERUsing MPI_Bcast for MPI communication。我在mpitutorial上发布了MPI教程。我的程序只是修改从根进程广播的数组,然后将修改后的数组收集到一个数组中并打印出来。所以,问题是,当我将下面列出的代码与未注释的MPI_Barrier(MPI_COMM_WORLD)一起使用时,我会得到一个错误。

代码语言:javascript
复制
#include "mpi/mpi.h"
#define N 4

void transform_row(int* row, const int k) {
  for (int i = 0; i < N; ++i) {
    row[i] *= k;
  }
}
const int root = 0;


int main(int argc, char** argv) {
  MPI_Init(&argc, &argv);
  int rank, ranksize;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &ranksize);
  if (rank == root) {
    int* arr = new int[N];
    for (int i = 0; i < N; ++i) {
      arr[i] = i * i + 1;
    }
    MPI_Bcast(arr, N, MPI_INT, root, MPI_COMM_WORLD);
  }
  int* arr = new int[N];
  MPI_Bcast(arr, N, MPI_INT, root, MPI_COMM_WORLD);
  //MPI_Barrier(MPI_COMM_WORLD);
  transform_row(arr, rank * 100);
  int* transformed = new int[N * ranksize];
  MPI_Gather(arr, N, MPI_INT, transformed, N, MPI_INT, root, MPI_COMM_WORLD);
  if (rank == root) {
    for (int i = 0; i < ranksize; ++i) {
      for (int j = 0; j < N ; j++) {
        printf("%i ", transformed[i * N + j]);
      }
      printf("\n");
    }
  }
  MPI_Finalize();
  return 0;
}

错误来自于线程数> 1。错误:

PMPI_Barrier中出现致命错误:消息被截断,错误堆栈: PMPI_Barrier(425)...................:MPI_Barrier(MPI_COMM_WORLD)失败

MPIR_Barrier_impl(332)..............:集合过程中失败

MPIR_Barrier_impl(327)..............:

MPIR_Barrier(292)...................:

MPIR_Barrier_intra(150).............:

barrier_smp_intra(111)..............:

MPIR_Bcast_impl(1452)...............:

MPIR_Bcast(1476)....................:

MPIR_Bcast_intra(1287)..............:

MPIR_Bcast_binomial(239)..........:

MPIC_Recv(353)......................:

MPIDI_CH3U_Request_unpack_uebuf(568):消息被截断;已收到16字节,但缓冲区大小为1

我知道buffer存在一些问题,但当我使用MPI_buffer_attach将大的buffer附加到MPI时,它并没有帮助。

看起来我需要增加这个缓冲区,但是我现在不知道该怎么做。

XXXXXX@XXXXXXXXX:~/test_mpi$ mpirun -版本

HYDRA构建详细信息:

代码语言:javascript
复制
Version:                                 3.2

Release Date:                            Wed Nov 11 22:06:48 CST 2015

所以请帮帮我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-03 07:22:10

一个问题是root等级调用MPI_Bcast()两次,但其他等级只调用一次。然后root rank使用未初始化的arr

MPI_Barrier()可能只会隐藏问题,但不能解决问题。

此外,请注意,如果N“足够大”,那么由root rank调用的第二个MPI_Bcast()可能会挂起。

以下是如何修改初始化/广播阶段来解决这些问题。

代码语言:javascript
复制
int* arr = new int[N];
if (rank == root) {
    for (int i = 0; i < N; ++i) {
        arr[i] = i * i + 1;
    }
MPI_Bcast(arr, N, MPI_INT, root, MPI_COMM_WORLD);

注在这种情况下,您可以简单地在所有队列上初始化arr,因此您甚至不需要广播阵列。

作为附注,MPI程序通常

代码语言:javascript
复制
#include <mpi.h>

然后使用mpicc进行编译/链接(这是一个包装器,它在设置包含/库路径并使用MPI库之后调用真正的编译器)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50660554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档