Search code examples
cperformanceparallel-processingmpihpc

Segmentation fault while using MPI_Type_contiguous


I am trying to understand the working of MPI_Type_contiguous for which I have written a code

    #include "mpi.h"
    #include <stdio.h>
     
    int main(int argc, char *argv[])
    {
        int myrank;
        MPI_Status status;
        MPI_Datatype type;
        int buffer[100];
        
        if(myrank==0)
        {
           for(int i=0;i<100;i++)
           {
               buffer[i]=i;
           }
        }
    
        MPI_Init(&argc, &argv);
     
        MPI_Type_contiguous( 100, MPI_CHAR, &type );
        MPI_Type_commit(&type);
     
        MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
     
        if (myrank == 0)
        {
            MPI_Send(buffer, 1, type, 1, 123, MPI_COMM_WORLD);
        }
        else if (myrank == 1)
        {
            MPI_Recv(buffer, 1, type, 0, 123, MPI_COMM_WORLD, &status);
        }
        if(myrank==1)
        {
           for(int i=0;i<100;i++)
           {
               printf("%d ",buffer[i]); 
           }
        }
     
        MPI_Finalize();
        return 0;
    }

But it gives me this error

===================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   PID 11963 RUNNING AT csews20
=   EXIT CODE: 139
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions

I am not able to understand the reason for this error as I am unable to spot the reason for the segmentation fault in my code.


Solution

  • Looking at your code I notice that the type of you array is int not char so you should use MPI_INT instead of MPI_CHAR. Moreover, you need to initialize the rank first. Just do:

     MPI_Init(&argc, &argv);
     MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    

    and then use the rank.

    #include "mpi.h"
    #include <stdio.h>
     
    int main(int argc, char *argv[])
    {
        int myrank;
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
       
        MPI_Status status;
        MPI_Datatype type;
        int buffer[100];
        
        for(int i=0;i<100;i++)
        {
            buffer[i]=i;
        }
         
        MPI_Type_contiguous( 100, MPI_CHAR, &type );
        MPI_Type_commit(&type);
        
     
        if (myrank == 0)
        {
            MPI_Send(buffer, 1, type, 1, 123, MPI_COMM_WORLD);
        }
        else if (myrank == 1)
        {
            MPI_Recv(buffer, 1, type, 0, 123, MPI_COMM_WORLD, &status);
        }
        
       if(myrank==1)
        {
            for(int i=0;i<100;i++)
            {
                printf("%d ",buffer[i]);    
            }
        }
        MPI_Finalize();
        return 0;
    }
    

    I also recommend reading the following SO Thread MPI_Type_contiguous vs primitive types.