我退出了。这是我曾经做过的最令人沮丧的事情。即使是非动态int数组也会导致段错误。但是,如果我将它声明为float / char无论数组,它都可以正常工作。
更新:如果我删除行MPI_Scatter(A[0], N, MPI_INT, A_row, N, MPI_INT, 0, MPI_COMM_WORLD);
,它可以正常工作。问题是我需要它......
我正在制作一个节目,但我有一个奇怪的问题。
以下代码正常(如果我们假设 N 是 p 的倍数):
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
void main(int argc, char** argv)
{
int my_rank, p, N, **A, *diagonals, *A_row;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
if (my_rank == 0) {
N = 4;
int *mem = malloc(N * N * sizeof(int));
A = malloc(N * sizeof(int*));
for(int i = 0; i < N; i++)
A[i] = mem + N*i;
}
MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
A_row = malloc (N * sizeof(int));
MPI_Scatter(A[0], N, MPI_INT, A_row, N, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Finalize();
}
但是,我需要分配另一个数组(对角线),如下所示:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
void main(int argc, char** argv)
{
int my_rank, p, N, **A, *diagonals, *A_row;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
if (my_rank == 0) {
N = 4;
int *mem = malloc(N * N * sizeof(int));
A = malloc(N * sizeof(int*));
for(int i = 0; i < N; i++)
A[i] = mem + N*i;
diagonals = malloc (N * sizeof(int));
}
MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
A_row = malloc (N * sizeof(int));
MPI_Scatter(A[0], N, MPI_INT, A_row, N, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Finalize();
}
我得到这个分段错误(如果它有帮助的话):
[teo-VirtualBox:02582] *** Process received signal ***
[teo-VirtualBox:02582] Signal: Segmentation fault (11)
[teo-VirtualBox:02582] Signal code: Address not mapped (1)
[teo-VirtualBox:02582] Failing at address: 0x1
[teo-VirtualBox:02582] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x113d0)[0x7faecc8d23d0]
[teo-VirtualBox:02582] [ 1] a[0x400c85]
[teo-VirtualBox:02582] [ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7faecc511830]
[teo-VirtualBox:02582] [ 3] a[0x4009a9]
[teo-VirtualBox:02582] *** End of error message ***
我错过了一些明显的东西吗?
顺便说一下,我没有使用free(),或者做任何具体的事情,因为这不是完整的代码。它只是我为测试而创建的辅助文件。
答案 0 :(得分:1)
说实话,我无法重现:
linux21:/home/users/grad1459/Desktop/parallel>mpiexec -np 4 a.out
linux21:/home/users/grad1459/Desktop/parallel>mpicc -Wall -std=c99 main.c
main.c: In function ‘main’:
main.c:9:15: warning: unused variable ‘status’ [-Wunused-variable]
main.c:8:29: warning: variable ‘diagonals’ set but not used [-Wunused-but-set-variable]
linux21:/home/users/grad1459/Desktop/parallel>mpiexec -np 4 a.out
ALL OK
ALL OK
ALL OK
ALL OK
linux21:/home/users/grad1459/Desktop/parallel>
与您的代码非常相似:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc, char** argv)
{
int my_rank, p, N, **A, *diagonals, *A_row;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
if (my_rank == 0) {
N = 4;
int *mem = malloc(N * N * sizeof(int));
A = malloc(N * sizeof(int*));
for(int i = 0; i < N; i++)
A[i] = mem + N*i;
diagonals = malloc (N * sizeof(int));
}
MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
A_row = malloc (N * sizeof(int));
MPI_Scatter(A[0], N, MPI_INT, A_row, N, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Finalize();
printf("ALL OK\n");
return 0;
}
因此,我认为您的虚拟机存在一些内存限制而malloc()
失败,检查其返回值以确保它不是NULL
,如下所示:How detect malloc failure?
这是我的版本:
linux21:/home/users/grad1459/Desktop/parallel>mpiexec --version
HYDRA build details:
Version: 3.1.3
Release Date: Wed Oct 8 09:37:19 CDT 2014
CC: gcc
CXX: g++
F77: gfortran
F90: gfortran
Configure options: '--disable-option-checking' '--prefix=/usr/local/mpich3' '--cache-file=/dev/null' '--srcdir=.' 'CC=gcc' 'CFLAGS= -O2' 'LDFLAGS= ' 'LIBS=-lpthread ' 'CPPFLAGS= -I/usr/local/USB/mpich-3.1.3/src/mpl/include -I/usr/local/USB/mpich-3.1.3/src/mpl/include -I/usr/local/USB/mpich-3.1.3/src/openpa/src -I/usr/local/USB/mpich-3.1.3/src/openpa/src -D_REENTRANT -I/usr/local/USB/mpich-3.1.3/src/mpi/romio/include'
Process Manager: pmi
Launchers available: ssh rsh fork slurm ll lsf sge manual persist
Topology libraries available: hwloc
Resource management kernels available: user slurm ll lsf sge pbs cobalt
Checkpointing libraries available:
Demux engines available: poll select
也许问题是你没有free()
你的记忆?你试过吗?
通常,在使用mpi时,尝试在连续的内存单元中分配2D动态数组(这样MPI就可以自由地使用它的步幅等)。通常,您可以使用以下函数执行此操作:
int** allocate2D(int** A, const int N, const int M) {
int i;
int *t0;
A = malloc(M * sizeof (int*)); /* Allocating pointers */
t0 = malloc(N * M * sizeof (int)); /* Allocating data */
for (i = 0; i < M; i++)
A[i] = t0 + i * (N);
return A;
}
void free2Darray(int** p, const int N) {
free(p[0]);
free(p);
}
正如我在2D dynamic array in continuous memory locations (C) 中解释的那样。
与运行时错误无关:Why do we need to use `int main` and not `void main` in C++?