alukard990 alukard990 - 1 month ago 6
C Question

Execution in local of a c-mpi program fails

I want to run, on my local pc, this c-mpi program Receiver process have to print their portion of array in order of rank. This is my code:

#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);
}
}
}
}

}


I use this 2 command to compile and execute the program:

mpicc -o sca_prod sca_prod.c
mpiexec -n 4 ./sca_prod


During the execution the program crash and it returns this error:

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


I'm using MPICH3.2 with Hydra executor and my OS is Ubuntu 14.04; the machine has a quadcore i7 processor. Please, can you help me? Thank you so much!

Answer

You have two subtle issues:

  1. MPI_SHORT_INT is the datatype in MPI for a struct { short, int }, for a short int use MPI_SHORT instead. This leads to overwriting memory.

  2. You use i as loop variable in two nested loops.

In general your code could be structured more better, to avoid issues like the second one.

  • Declare variables as locally as possible, especially loop variables within the loop declaration (c99).
  • Use more descriptive variable names.
  • Hide things like printing an array in functions.
  • Format your code properly.

Also learn to use a (parallel) debugger.