我正在尝试编写一个简单的方法来并行读取文件,其中每个进程都会从文件中读取多个int,以便将数据拆分到每个进程,但是我遇到了分段错误,我无法理解为什么或者如何解决它。这是我写的代码:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#define NUM_INTS 5
int main (int argc, char** argv) {
MPI_Init(&argc, &argv);
int i;
int rank,processes,name_len;
const int root=0;
int *buf;
char *filename = "file.txt";
MPI_File fh;
MPI_Status status;
MPI_Offset offset;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &processes);
MPI_Get_processor_name(processor_name, &name_len);
MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
buf = malloc(NUM_INTS * sizeof(int));
MPI_File_set_view(fh, 0, MPI_INT, MPI_INT, (char *)NULL, MPI_INFO_NULL);
offset = rank * NUM_INTS;
MPI_File_read_at(fh, offset, buf, NUM_INTS, MPI_INT, &status);
MPI_Barrier(MPI_COMM_WORLD);
MPI_File_close(&fh);
for (i=0;i<NUM_INTS;i++)
printf("rank %d data[%d] = %d\n", rank, i, buf[i]);
free(buf);
MPI_Finalize();
return 0;
}
该文件包含10个整数,我试图将其拆分为2个进程。 我认为问题在于MPI_File_read_at,因为所有打印都可以使用该行
提前致谢
答案 0 :(得分:3)
你为什么要经过&#34; null&#34;你的数据类型表示? (事实上,你为什么要设置文件视图?)
如果您遵循了@Colin Cassidy的建议,您的背后跟踪指向问题:它不是MPI_File_read_at,它是MPI_File_set_view。
删除该行,或将(char *)NULL更改为&#34; native&#34;
此外,您应该检查您的返回值,但这对您没有帮助。请参阅我对此问题的回答:How to use and interpret MPI-IO Error codes?
MPICH(或者更确切地说是ROMIO)不应该对您的垃圾输入进行分段。我正在审核这个补丁。它有一个有趣的副作用,让你调用MPI_File_set_view返回一个你忽略的错误,然后你的代码的其余部分按你的意愿行事。
答案 1 :(得分:0)
我不完全了解MPI功能,但我不能100%确定您的问题所在,但是这里有一些常用的调试技巧可以用来尝试追踪问题。
1)使用调试器。 GDB或类似的人在这里是你的朋友,你应该能够用它来逐行浏览你的程序,随时观察所有变量,这应该可以帮助你找出它产生分段错误的确切位置,你应该知道当时变量的值。这应该有助于追踪问题所在。
2)如果你有一个核心转储,你可以再次使用gdb来执行事后调试,并从崩溃点获得一个堆栈跟踪,这可能会解决这个问题。
3)如果你无法使用“printf()”调试方法,在计算它时调试/转储所有内容,这可能会有所帮助,但我在过去发现这可能导致内存位置需要更改的内容,有时会删除崩溃...请注意,这不能解决您的问题,您只需重新安排内存,以便在当前情况下不会崩溃。