我想在我的本地电脑上运行这个c-mpi程序Receiver进程必须按照排名顺序打印它们的数组部分。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "mpi.h"
#define MAX_DIM 22
#define NPROC 4
#define TRUE 1
#define FALSE 0
void print(int*,int*,int*,int*,int*,int*);
int main(int argc, char* argv[]){
int i,rank,*x,*y,nproc;
int partition=MAX_DIM/NPROC;
int sendcount[NPROC],offset[NPROC];
int k=MAX_DIM%NPROC;
for(i=0;i<NPROC;i++){
sendcount[i]=partition;
if(i<k)
sendcount[i]++;
}
offset[0]=0;
for(i=1;i<NPROC;i++)
offset[i]=offset[i-1]+sendcount[i-1];
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&nproc);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if(rank==0){
srand(time(NULL));
x=(int*)malloc(sizeof(int)*MAX_DIM);
y=(int*)malloc(sizeof(int)*MAX_DIM);
for(i=0;i<MAX_DIM;i++){
x[i]=rand()%100+1;
y[i]=rand()%100+1;
}
printf("Sender[%d] => array <x>: \n",rank);
for(i=0;i<MAX_DIM;i++){
if(i%10==0)
printf("\n");
printf("%d ",x[i]);
}
printf("\nSender[%d] => array <y>: \n",rank);
for(i=0;i<MAX_DIM;i++){
if(i%10==0)
printf("\n");
printf("%d ",y[i]);
}
}
int* rvett1=(int*)malloc(sizeof(int)*sendcount[rank]);
int* rvett2=(int*)malloc(sizeof(int)*sendcount[rank]);
MPI_Scatterv(x,&sendcount[rank],&offset[rank],MPI_INT,rvett1,sendcount[rank],MPI_INT,0,MPI_COMM_WORLD);
MPI_Scatterv(y,&sendcount[rank],&offset[rank],MPI_INT,rvett2,sendcount[rank],MPI_INT,0,MPI_COMM_WORLD);
print(&rank,&nproc,rvett1,&sendcount[rank],rvett2,&sendcount[rank]);
if(rank==0){
free(x);
free(y);
}
free(rvett1);
free(rvett2);
MPI_Finalize();
printf("Exit program! \n");
return 0;
}
void print(int* rank,int* nproc,int* rvett1,int* dim1,int* rvett2,int* dim2){
int i,tag=0;
short int token=FALSE;
MPI_Status info;
if(*rank==0){
printf("\nReceiver[%d] => part of array <x>, dimension: %d \n",*rank,*dim1);
for(i=0;i<*dim1;i++){
if(i%10==0)
printf("\n");
printf("%d ",rvett1[i]);
}
printf("\nReceiver[%d] => part of array <y>, dimension: %d \n",*rank,*dim1);
for(i=0;i<*dim2;i++){
if(i%10==0)
printf("\n");
printf("%d ",rvett2[i]);
}
token=TRUE;
printf("\nStarter[%d] sends a print token \n",*rank);
MPI_Send(&token,1,MPI_SHORT_INT,1,tag+1,MPI_COMM_WORLD);
}
else{
for(i=1;i<*nproc;i++){
if(*rank==i){
MPI_Recv(&token,1,MPI_SHORT_INT,i-1,tag+i,MPI_COMM_WORLD,&info);
printf("Receiver[%d] => OK print \n ",i);
printf("\nReceiver[%d] => part of array <x>, dimension: %d \n",*rank,*dim1);
for(i=0;i<*dim1;i++){
if(i%10==0)
printf("\n");
printf("%d ",rvett1[i]);
}
printf("\nReceiver[%d] => part of array <y>, dimension: %d \n",*rank,*dim1);
for(i=0;i<*dim2;i++){
if(i%10==0)
printf("\n");
printf("%d ",rvett2[i]);
}
if(*rank<(*nproc)-1){
printf("Receiver[%d] sends next token \n",i);
MPI_Send(&token,1,MPI_SHORT_INT,i+1,tag+i+1,MPI_COMM_WORLD);
}
}
}
}
}
我使用这个2命令来编译和执行程序:
mpicc -o sca_prod sca_prod.c
mpiexec -n 4 ./sca_prod
在执行期间程序崩溃并返回此错误:
Sender[0] => array <x>:
92 37 80 73 68 24 42 72 88 26
47 25 24 98 47 92 72 100 34 20
76 97
Sender[0] => array <y>:
17 62 55 70 53 44 73 72 19 47
11 83 29 30 56 39 80 51 24 54
96 70
Receiver[0] => part of array <x>, dimension: 6
92 37 80 73 68 24
Receiver[0] => part of array <y>, dimension: 6
17 62 55 70 53 44
Starter[0] sends a print token
Receiver[1] => OK print
Receiver[1] => part of array <x>, dimension: 6
42 72 88 26 47 25
Receiver[1] => part of array <y>, dimension: 6
73 72 19 47 11 83 Receiver[6] sends next token
Fatal error in MPI_Send: Invalid rank, error stack:
MPI_Send(174): MPI_Send(buf=0x7ffe216fb636, count=1, MPI_SHORT_INT, dest=7, tag=7, MPI_COMM_WORLD) failed
MPI_Send(100): Invalid rank has value 7 but must be nonnegative and less than 4
我正在使用带有Hydra执行器的MPICH3.2,我的操作系统是Ubuntu 14.04;这台机器有一个四核i7处理器。拜托,你能帮帮我吗?非常感谢你!
答案 0 :(得分:0)
你有两个微妙的问题:
MPI_SHORT_INT
是MPI中struct { short, int }
的数据类型,而short int
使用的是MPI_SHORT
。这会导致覆盖内存。
您在两个嵌套循环中使用i
作为循环变量。
一般来说,您的代码可以更好地构建,以避免第二个问题。
还学习使用(并行)调试器。