通信器 MPI_COMM_WORLD 上的 MPI Scatter 错误

Posted

技术标签:

【中文标题】通信器 MPI_COMM_WORLD 上的 MPI Scatter 错误【英文标题】:MPI Scatter error on communicator MPI_COMM_WORLD 【发布时间】:2022-01-01 15:26:03 【问题描述】:

由于我无法修复的 MPI 分散错误,以下代码在运行时失败。在关注文档和其他类似的错误页面时,我没有看到任何问题。请帮忙。我正在使用 openmpi/4.0.5-gcc。

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"

#define UPPER_LIMIT 4
#define master 0
int main(int argc, char *argv[])

  int *data;
  int process_id, total_process, temp_result;
  int i, tag, final_result;
  
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &process_id);
  MPI_Comm_size(MPI_COMM_WORLD, &total_process);
  MPI_Status status;

  if ( total_process > UPPER_LIMIT )
  
        if ( process_id == 0 )
          printf("max allowed processes limit [%d] exceeded.\n", UPPER_LIMIT);
        exit(0);
  

  final_result = 0;
  
  for ( i = 0; i < total_process; i++)
      data[i] = (int)i;
  
    int j;
    for(j = 0; j < total_process; j++) 
        printf("%d ", data[j]);
        if(j==total_process-1)
            printf("*** %d\n", process_id);
    
    
    MPI_Scatter(data, total_process, MPI_INT, &temp_result, 1, MPI_INT, 0, MPI_COMM_WORLD);
    if(process_id!=master)
        temp_result = temp_result/process_id;
        MPI_Reduce(&temp_result, &final_result, 1, MPI_INT, MPI_SUM, 1, MPI_COMM_WORLD);  
    
    
    if(final_result>0)
        tag = process_id;
        MPI_Send(&final_result, 1, MPI_INT, 0, tag, MPI_COMM_WORLD);
    
    
    if(process_id==master)
        MPI_Recv(&final_result, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    
    
  MPI_Finalize();

  return 0;


错误日志

0 1 2 3 *** 0
0 1 2 3 *** 1
0 1 2 3 *** 2
0 1 2 3 *** 3
 *** An error occurred in MPI_Scatter
 *** reported by process [1855324161,0]
 *** on communicator MPI_COMM_WORLD
 *** MPI_ERR_TRUNCATE: message truncated
 *** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,
 ***    and potentially your MPI job)

MPI_Scatter 文档

MPI_Scatter 将数据从一个进程发送到通信器中的所有其他进程

概要 int MPI_Scatter(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm 通信)

输入参数

sendbuf - 发送缓冲区的地址(选择,仅在根节点有效)

sendcount - 发送到每个进程的元素数(整数,仅在根处有效)

sendtype - 发送缓冲区元素的数据类型(仅在根处有效)(句柄)

recvcount - 接收缓冲区中的元素数(整数)

recvtype - 接收缓冲区元素的数据类型(句柄)

root - 发送进程的等级(整数)

comm - 通讯器(句柄)

输出参数

recvbuf - 接收缓冲区的地址(选择)


更新

将 MPI_Scatter 发送计数更新为 1 后,上述错误消失了,但程序保持理想状态,并且没有打印任何放置在 MPI_Scatter 行之后的内容。

MPI_Scatter(data, 1, MPI_INT, &amp;temp_result, 1, MPI_INT, 0, MPI_COMM_WORLD);

解决方案

MPI_Reduce 需要被所有处理器调用。因此,从条件块中删除它可以解决问题。

【问题讨论】:

本站可用于在线执行以上代码。 codingame.com/playgrounds/349/introduction-to-mpi/hello-world 【参考方案1】:

您引用了相关行:“sendcount - 发送到每个进程的元素数(整数”。因此,如果您向每个进程发送 1 个元素,则需要将 sendcount 设置为 1,而不是 total_process

【讨论】:

非常感谢您的回答。我确实放了 1 并且它通过了 Scatter 块但程序变得空闲。你知道为什么会这样吗? 您的发送和接收是否陷入僵局? 我在散点线后面放了一个打印语句,甚至注释了发送和接收代码。但我没有看到散点线后打印的任何内容,它仍然保持理想状态。我认为问题仍然来自散射线。我能弄明白。 条件句中有一个MPI_Reduce。那是行不通的。所有进程都需要调用它。 它有效。非常感谢。我不知道我是怎么错过那条线的。

以上是关于通信器 MPI_COMM_WORLD 上的 MPI Scatter 错误的主要内容,如果未能解决你的问题,请参考以下文章

连续 MPI 非阻塞调用

MPI_Type_commit 是不是隐式调用 MPI_COMM_WORLD 中所有进程的屏障?

MPI 屏障 C++

MPI_ERR_TRUNCATE:广播

Openmpi mpmd 获取通信大小

vs2019运行mpi如何改变进程数, 运行结果总是一个进程,进程号为0; 如何改变VS2019进程数? return 0;