1

Following is a program which aims to sum two matrices of size 128 * 128 splitting the tasks into 8 process, hence each process sums 16 rows of matrices.

int main(int argc, char** argv)
{
    int rank;

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

    int **matrixA;
    int **matrixB;
    int **resultMatrix = malloc(ROWS * sizeof(int *));

    if (rank == 0) {
       matrixA = generateMatrix();
       matrixB = generateMatrix();
       for (i = 0; i < COLS; i++)
          resultMatrix[i] = malloc(COLS * sizeof(int));
    }

    int **auxA = malloc(16 * sizeof(int *));
    int **auxB = malloc(16 * sizeof(int *));
    int **auxC = malloc(16 * sizeof(int *));

    int i;
    int row, col;

    for (i = 0; i < 16; i++)
    {
       auxA[i] = malloc(COLS * sizeof(int));
       auxB[i] = malloc(COLS * sizeof(int));
       auxC[i] = malloc(COLS * sizeof(int));
    }

    MPI_Scatter(&(matrixA[0][0]), 16*COLS, MPI_INT, &(auxA[0][0]), 16*COLS, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Scatter(&(matrixB[0][0]), 16*COLS, MPI_INT, &(auxB[0][0]), 16*COLS, MPI_INT, 0, MPI_COMM_WORLD);

    char hostname[HOST_NAME_MAX];
    if (! gethostname(hostname, sizeof hostname) == 0)
        perror("gethostname");

    for (row = 0; row < 16; row++)
    {
       for (col = 0; col < COLS; col++)
       {
           auxC[row][col] = auxA[row][col] + auxB[row][col];
       }
    }

    printf("Process Node %s %d\n done",hostname, rank);

    MPI_Gather(&auxC[0][0], 16*COLS, MPI_INT, &(resultMatrix[0][0]), 1, MPI_INT, 0, MPI_COMM_WORLD);

    if (rank == 0) {
       printMatrix(resultMatrix);
    }

    MPI_Finalize();
}   

Getting the following error message

[xxx115:12933] *** Process received signal ***
[xxx115:12933] Signal: Segmentation fault (11)
[xxx115:12933] Signal code: Address not mapped (1)
[xxx115:12933] Failing at address: 0x2
[xxx115:12934] *** Process received signal ***
[xxx115:12934] Signal: Segmentation fault (11)
[xxx115:12934] Signal code: Address not mapped (1)
[xxx115:12934] Failing at address: 0x2
[xxx115:12936] *** Process received signal ***
[xxx115:12936] Signal: Segmentation fault (11)
[xxx115:12936] Signal code: Address not mapped (1)
[xxx115:12936] Failing at address: 0x2
[xxx115:12933] [ 0] /lib64/libpthread.so.0[0x32ff00f7e0]
[xxx115:12933] [ 1] ./hw5[0x400bd4]
[xxx115:12933] [ 2] /lib64/libc.so.6(__libc_start_main+0xfd)[0x32fe41ed1d]
[xxx115:12933] [ 3] ./hw5[0x400879]
[xxx115:12936] [ 0] /lib64/libpthread.so.0[0x32ff00f7e0]
[xxx115:12936] [ 1] ./hw5[0x400bd4]
[xxx115:12936] [ 2] [wsu115:12933] *** End of error message ***

As i observe from other questions like this and this, segmentation fault arises when array makes an attempt to access memory out of its bounds.

However, i am not what part of program is causing this error. What can i do to fix the problem.

EDIT

After going through the comments, I realized that previous program was cluttered with lot of pointers. Here is a simplified version that is working without any error, but still not giving the expected output.

int **generateMatrix() 
{
    int **matrix = (int **)malloc(ROWS * sizeof(int *));
    int i;
    for (i = 0; i < ROWS; i++)
         matrix[i] = (int *)malloc(COLS * sizeof(int));

    int row, col;
    for (row = 0; row < ROWS; row++) 
    {
        for (col = 0; col < COLS; col++) 
        {
            matrix[row][col] = col; 
        }
    }
    return matrix;
}

int main(int argc, char** argv)
{
    int rank, world_size;

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

    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    int **matrixA;
    int **matrixB;
    int resultMatrix[128][128];

    int auxA[16][128];
    int auxB[16][128];
    int auxC[16][128];

    if (rank == 0) {
        matrixA = generateMatrix();
        matrixB = generateMatrix();
    }

    MPI_Scatter(matrixA, 16*COLS, MPI_INT, auxA, 16*COLS, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Scatter(matrixB, 16*COLS, MPI_INT, auxB, 16*COLS, MPI_INT, 0, MPI_COMM_WORLD);

    char hostname[HOST_NAME_MAX];
    if (! gethostname(hostname, sizeof hostname) == 0)
      perror("gethostname");

    int row, col; 
    for (row = 0; row < 16; row++)
    {
        for (col = 0; col < COLS; col++)
        {
            auxC[row][col] = auxA[row][col] + auxB[row][col];
        }
    }

    printf("Process Node %s %d done\n",hostname, rank);

    MPI_Gather(auxC, 16*COLS, MPI_INT, resultMatrix, 16*COLS, MPI_INT, 0, MPI_COMM_WORLD);

    if (rank == 0) {
        printMatrix(resultMatrix);
    }

    MPI_Finalize();
    return 0;
}   
Sanchit Jain
  • 119
  • 3
  • 15
  • 2
    Compile with all warnings and debug info: `gcc -Wall -Wextra -g`. **Use the debugger `gdb`** – Basile Starynkevitch Nov 05 '17 at 19:09
  • 2
    BTW, `malloc` can fail and then gives `NULL` – Basile Starynkevitch Nov 05 '17 at 19:09
  • `mallo` may not be the problem. I tried to run the code without using MPI functionalities, with success. – Sanchit Jain Nov 05 '17 at 19:25
  • But did you use the debugger when trying? – Basile Starynkevitch Nov 05 '17 at 19:26
  • no i didn't...it is running without any issues, so didn't use debugger, but let me check with debugger too. – Sanchit Jain Nov 05 '17 at 19:27
  • 1
    **Why** are you casting the return value of `malloc` – Antti Haapala -- Слава Україні Nov 05 '17 at 19:49
  • @AnttiHaapala, because there seems to be confusion between C and C++. – Jens Gustedt Nov 05 '17 at 19:56
  • C and C++ are different languages. Your code looks like C to me, so I removed the C++ tag. In C you don't have to cast the return of `malloc` and in C++ you wouldn't use it at all. Also C has proper 2D matrices, there is no need to fake them with arrays to pointers. Most of your problems will probably go away when you use proper types. – Jens Gustedt Nov 05 '17 at 20:00
  • @AnttiHaapala Yes i agree casting was redundent, wasn't aware about it. – Sanchit Jain Nov 05 '17 at 20:07
  • @JensGustedt: using arrays to pointers to dynamically build 2D arrays – Sanchit Jain Nov 05 '17 at 20:08
  • @BasileStarynkevitch: gcc- Wall -Wextra doesn't output anything. Still learning to use gbd with MPI – Sanchit Jain Nov 05 '17 at 20:51
  • @BasileStarynkevitch : I used the debugger and found the error. It was on MPI_Gather line. The argument after &resultMatrix is not correct. Now, the debugger is running the program correctly, but when i run on server i am still getting error. – Sanchit Jain Nov 05 '17 at 21:32
  • 4
    MPI doesn't handle 2D arrays where each row is independently `malloc`'d. Use contiguous arrays instead, i.e. `int *a = malloc(rows * cols * sizeof *a);` You can create an index pointer array with elements that point to the beginning of each row in the contiguous memory in order to still use the convenient array syntax - see [this answer](https://stackoverflow.com/a/5901671/1374437). – Hristo Iliev Nov 05 '17 at 21:58
  • That is one of the differences between C and C++. C has dynamic arrays, so there is really no need for doing kruft like this. – Jens Gustedt Nov 05 '17 at 22:26
  • @HristoIliev : Yes. But i am facing trouble in allocating values to matrixA and matrixB in generateMatrix function using contiguous pointers. The values that are to be assigned are in increasing order from 1 to 128, for every 128 rows. – Sanchit Jain Nov 06 '17 at 13:37
  • You are still trying to scatter from an array of pointers to each row and this is NOT going to work. See the answer I've linked in my previous comment. It shows how to create an index into the contiguous memory so that you can use the `arr[x][y]` notation. – Hristo Iliev Nov 07 '17 at 07:18
  • Yes, i figured out the correct way to do it. I am not sure what to do with the question now? There is no option to delete the question too, as i understand. – Sanchit Jain Nov 07 '17 at 18:17

0 Answers0