i退出。这是我有史以来最令人沮丧的事情。即使是非动态INT阵列也会引起segfault。但是,如果我将其声明为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()或执行任何特定的操作,因为这不是完整的代码。这只是我为测试而创建的侧面文件。
说实话,我无法复制:
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 OKn");
return 0;
}
结果,我认为您的虚拟箱具有一些内存限制,并且您的malloc()
失败,请检查其返回值以确保它不是NULL
,因此:如何检测Malloc故障?
这是我的版本:
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);
}
正如我在连续内存位置(C)中2D动态阵列中解释的那样。
与您的运行时错误无关:为什么我们需要在C 中使用`int main'而不是`void main'?