MPI_Reduce()程序出现分段错误
我开始学习使用C和OpenMPI库进行并行编程。所以现在一切看起来都有点太复杂了 我正在尝试执行一个程序,其中包含多个数据: 大师: -初始化数组 -细分 -将相同大小的数据位发送到不同的进程(从进程) 奴隶: -进程更改数组值并计算所有新元素的总和 -将更改后的阵列发送回主机 大师: -进行集体交流,以收集和汇总新值的总和 -打印接收到的每个新数组的前五个元素以及新值的全局和。 -打印所花的时间 这就是我写的:MPI_Reduce()程序出现分段错误,c,segmentation-fault,mpi,C,Segmentation Fault,Mpi,我开始学习使用C和OpenMPI库进行并行编程。所以现在一切看起来都有点太复杂了 我正在尝试执行一个程序,其中包含多个数据: 大师: -初始化数组 -细分 -将相同大小的数据位发送到不同的进程(从进程) 奴隶: -进程更改数组值并计算所有新元素的总和 -将更改后的阵列发送回主机 大师: -进行集体交流,以收集和汇总新值的总和 -打印接收到的每个新数组的前五个元素以及新值的全局和。 -打印所花的时间 这就是我写的: #include <stdio.h> #include <std
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#define ARRAYSIZE 16000000
int main (int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int myrank;
char name[100];
int result;
int size = 0;
int number;
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
MPI_Request request;
int buffer;
int count;
double t1, t2;
MPI_Comm_size (MPI_COMM_WORLD,&size);
int cells = ARRAYSIZE/size;
float array[cells];
if (myrank == 0) {
t1 = MPI_Wtime();
t2 = MPI_Wtime();
MPI_Get_processor_name(name, &result);
// ********************** INICIALIZANDO ARRAY **********************
int i; /* loop variable */
float data[ARRAYSIZE]; /* the intial array */
printf("Starting serial array example...\n");
printf("Using array of %d floats. Requires %ld bytes\n",ARRAYSIZE,sizeof(data));
/* Initialize the array */
printf("Initializing array...\n");
for(i=0; i<ARRAYSIZE; i++)
data[i] = i * 1.0;
/* Print a few sample results */
printf("Sample results\n");
printf(" data[1]=%e\n", data[1]);
printf(" data[100]=%e\n", data[100]);
printf(" data[1000]=%e\n", data[1000]);
printf(" data[10000]=%e\n", data[10000]);
printf(" data[100000]=%e\n", data[100000]);
printf(" data[1000000]=%e\n", data[1000000]);
printf("\nAll Done!\n");
// ********************** ARRAY INICIALIZADO **********************
MPI_Comm_size (MPI_COMM_WORLD,&size);
printf("Total of tasks: %d", size);
printf("Each task process %d cells", ARRAYSIZE/size);
int cells = ARRAYSIZE/size;
int id_task;
for(id_task = 0; id_task < size; id_task++) {
//float array[cells];
int i=0;
for(i=0; i<cells; i++)
array[i] = i * (id_task+1.0);
MPI_Send(&array[id_task*cells], cells, MPI_FLOAT, id_task, 0, MPI_COMM_WORLD);
}
printf("master: %d at processor: %s\n",myrank, name);
}
MPI_Recv(array, cells, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
int i;
float resultado;
for(i=0; i<cells; i++)
array[i] = i * (myrank+1.0);
if(myrank!=0){
MPI_Send(array, cells, MPI_FLOAT, 0, 0, MPI_COMM_WORLD);
}
MPI_Reduce(&array, &resultado, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);
if (myrank == 0) {
int j;
for(j=0; j<cells; j++){
for(i=0; i<5; i++){
printf("| %lf ",array[i*j]);
}
}
//t1 = MPI_Wtime();
t2 = MPI_Wtime();
MPI_Get_processor_name(name, &result);
printf("master: %d at processor: %s\ntime: %lf\n",myrank, name,t2-t1);
}
MPI_Finalize();
}
#包括
#包括
#包括“mpi.h”
#定义阵列化16000000
int main(int argc,char*argv[]){
MPI_Init(&argc,&argv);
int-myrank;
字符名[100];
int结果;
int size=0;
整数;
MPI_Comm_rank(MPI_Comm_WORLD和myrank);
MPI_请求;
int缓冲区;
整数计数;
双t1,t2;
MPI_通信大小(MPI_通信世界和大小);
int cells=阵列化/大小;
浮点数组[单元];
如果(myrank==0){
t1=MPI_Wtime();
t2=MPI_Wtime();
MPI获取处理器名称(名称和结果);
//*************************INICIALIZANDO阵列**********************
int i;/*循环变量*/
浮点数据[ARRAYSIZE];/*初始数组*/
printf(“启动串行阵列示例…\n”);
printf(“使用%d个浮点数的数组。需要%ld个字节\n)”,ARRAYSIZE,sizeof(数据));
/*初始化数组*/
printf(“初始化数组…\n”);
对于(i=0;i您很可能有:
然后,您将(在上)声明一个本地
这是不合理的。一个典型的调用堆栈帧最多应该有几千字节(因为整个调用堆栈通常被限制在几兆字节或更少)。您需要一个64MB的。您应该使用,所以声明float*data=NULL;
并在适当的位置使用(以及更晚的free
;您应该避免).别忘了
使用所有警告和调试信息编译:gcc-Wall-Wextra-g
,然后使用调试器检查是否发生堆栈溢出
阅读有关的文档。您可能还希望使用类似于-Wstack usage=2048
for(id_task = 0; id_task < size; id_task++) {
//float array[cells];
int i=0;
for(i=0; i<cells; i++)
array[i] = i * (id_task+1.0);
MPI_Send(&array[id_task*cells], cells, MPI_FLOAT, id_task, 0, MPI_COMM_WORLD);
}
秩0上没有匹配的MPI\u Recv()
,因此这也可能会死锁
MPI_Reduce(&array, &resultado, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);
这将对所有列组中的数组[0]
求和,并将结果存储在列组0上的resultado
中。我不确定这是否真的是您想要的(但我不知道您试图实现什么,所以这可能没问题).使用所有警告和调试信息编译:gcc-Wall-Wextra-g
然后使用调试器gdb
尝试使用调试器插入代码,找到导致错误的行,并将其添加到问题主体中。作为旁注,您可能需要yoMPI_Scatterv()
将数据
数组放入数组
如下?float*data=NULL;data=(float*)malloc(ARRAYSIZE);您还需要调用(很久以后)free
mpirun注意到节点上PID为0的进程秩0在信号11(分段错误:11)时退出。如果我尝试的话“$HOME/opt/usr/local/bin/mpicc-o-Wall-Wextra-g programa3-r1./programa3-r1.c
”它给出:“ld:无法链接架构x86的主可执行文件“programa3-r1”\u 64 clang:错误:链接器命令失败,退出代码为1(使用-v查看调用)“谢谢你,先生!当我尝试动态分配float*data;/*初始数组*/data=(float*)malloc(sizeof(float)*ARRAYSIZE);
谢谢你,先生!从MPI的角度来看,这确实是错误的,我必须实现一个MPI_Recv(…)在循环中接收来自所有任务的数据。还更正了MPI_Reduce(…)中的错误参数
for(id_task = 0; id_task < size; id_task++) {
//float array[cells];
int i=0;
for(i=0; i<cells; i++)
array[i] = i * (id_task+1.0);
MPI_Send(&array[id_task*cells], cells, MPI_FLOAT, id_task, 0, MPI_COMM_WORLD);
}
if(myrank!=0){
MPI_Send(array, cells, MPI_FLOAT, 0, 0, MPI_COMM_WORLD);
}
MPI_Reduce(&array, &resultado, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);