Click here to Skip to main content
15,889,462 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello, I've just recently been messing around with my parallel programming in MPI (OpenMP after this!) and I ran a code to multiply matrices on a virtual machine (Ubuntu) with 4 cores. Unfortunately, I got an error:

Fatal error in PMPI_Gather: Invalid buffer pointer, error stack:
PMPI_Gather(856): MPI_Gather(sbuf=0x601d20, scount=100, MPI_FLOAT, rbuf=0x601d20, rcount=100, MPI_FLOAT, root=0, MPI_COMM_WORLD) failed
PMPI_Gather(797): Buffers must not be aliased



This is the code obtained from SpeedGoComputing:
C++
#include <mpi.h>

const int size = 20;

float a[20][20];
float b[20][20];
float c[20][20];

void multiply(int istart, int iend)
{
	int i,j,k;
    for (i = istart; i <= iend; ++i) {
        for (j = 0; j < size; ++j) {
            for (k = 0; k < size; ++k) {
                c[i][j] += a[i][k] * b[k][j];
            }
        }
    }
}

int main(int argc, char* argv[])
{
    int rank, nproc;
    int istart, iend;

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

    if (rank == 0) {
        // Initialize buffers.
		int i;
		int j;
        for (i = 0; i < size; ++i) {
            for (j = 0; j < size; ++j) {
                a[i][j] = (float)i + j;
                b[i][j] = (float)i - j;
                c[i][j] = 0.0f;
            }
        }
    }

    // Broadcast matrices to all workers.
    MPI_Bcast(a, size*size, MPI_FLOAT, 0,MPI_COMM_WORLD);
    MPI_Bcast(b, size*size, MPI_FLOAT, 0,MPI_COMM_WORLD);
    MPI_Bcast(c, size*size, MPI_FLOAT, 0,MPI_COMM_WORLD);

    // Partition work by i-for-loop.
    istart = (size / nproc) * rank;
    iend = (size / nproc) * (rank + 1) - 1;

    // Compute matrix multiplication in [istart,iend]
    // of i-for-loop.
    // C <- C + A x B
    multiply(istart, iend);

    // Gather computed results.
    MPI_Gather(c + (size/nproc*rank),
               size*size/nproc,
               MPI_FLOAT,
               c + (size/nproc*rank),
               size*size/nproc,
               MPI_FLOAT,
               0,
               MPI_COMM_WORLD);
			   



    if (rank == 0) {
        // Compute remaining multiplications
        // when size % nproc > 0.
        if (size % nproc > 0) {
            multiply((size/nproc)*nproc, size-1);
        }
    }

    MPI_Finalize();
    return 0;
}


What I have tried:

I suspect there's something wrong with the sendbuf argument of MPI_Gather, so I changed it to MPI_IN_PLACE but even that didn't work. I tried MPI_gatherV too and that didn't work.

I've tried debugging this in Visual Studio and it says there was a breakpoint reached. At the "if (rank == 0)": line. Perhaps it has something to do with pointers and addresses, I'm not very sure. I will be reading up on it.
If anyone could help, please and thank you! I'm not very adept at C.
Posted
Updated 20-Apr-16 1:08am

1 solution

In your call to
MPI_Gather(c + (size/nproc*rank),
    size*size/nproc,
    MPI_FLOAT,
    c + (size/nproc*rank),
    size*size/nproc,
    MPI_FLOAT,
    0,
    MPI_COMM_WORLD);

the send and receive buffers are identical which is not allowed when not using the MPI_IN_PLACE[^] option.
 
Share this answer
 
v3
Comments
Member 12472890 20-Apr-16 7:44am    
The error still persists when I've replaced sendbuf with MPI_IN_PLACE
Jochen Arndt 20-Apr-16 7:52am    
MPI_IN_PLACE is a special flag (read the link from my post). I will update the link to jump to the description.

You should probably not use that but provide an explicit recv buffer.
Member 12472890 20-Apr-16 8:03am    
So sorry, I didn't realize it was a link. I will review the code and get back to you

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900