Birdman
Birdman

Reputation: 1524

MPI_Scatter & MPI_Gather with std::vector

I'm new to MPI programming. I'm using C++ since I want to use a vector instead of an array (so user can dynamically choose size of what will be a grid for a game (Conway's Game of Life), instead of hardcoded array size).

ASSUME: There are 4 processes (p = 4)

Here's my code:

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

vector<CELL> *gameBoard = NULL;

if (rank == 0)
{
    //create the gameboard on just the root process
    gameBoard = new vector<CELL>();
    gameBoard->resize(16);
}

//create a partialGrid on EACH process
vector<CELL> *partialGrid = new vector<CELL>();
partialGrid->resize(4);

int partialSize = 4;

MPI_Scatter(gameBoard, partialSize, mpi_cell, partialGrid, partialSize, mpi_cell, 0, MPI_COMM_WORLD);

//do something on each process
cout << "HI!!! I'm scattered process number " << rank << endl;
//ideally, do something to the sub vector here (once it works)

vector<CELL> *rbuf = NULL; //Just make null for all other processes. Valid receive buffer only needed for root (rank = 0)

if (rank == 0)
{
    //make sure the receiving buff is created (for just the root rank 0)
    vector<CELL> *rbuf = new vector<CELL>();
    rbuf->resize(16);
    cout << "RANK 0 TEST!" << endl;
}

MPI_Gather(&partialGrid, (pow(n, 2) / p), mpi_cell, &rbuf, (pow(n, 2) / p), mpi_cell, 0, MPI_COMM_WORLD);

The goal is (for now hardcoded) split our vector of 16 elements into 4 sub vectors, one for each of our 4 processes to do something to.

I think my logic with rank 0 is correct. I'm only creating a receive buffer for MPI_Gather on the rank process and I'm creating the subvector for EACH process before MPI_Scatter. I've tried numerous things and MPI_Scatter always fails. Please help!

Note: CELL is a struct of nine int values. mpi_cell is a custom type I created in my MPI program. Excluded code for simplicity, but you could replace CELL with int and mpi_cell with MPI_INT if you want to test.

I am receiving a segmentation fault:

enter image description here

Upvotes: 1

Views: 6054

Answers (1)

Evg
Evg

Reputation: 26272

As asynts noted in the comment, your news are wrong. The correct way to use std::vector is the following:

std::vector<CELL> gameBoard;
if (rank == 0)
    gameBoard.resize(16);

std::vector<CELL> partialGrid;
partialGrid.resize(4);

MPI_Scatter(gameBoard.data(), 4, mpi_cell, partialGrid.data(), 4, mpi_cell, 0, MPI_COMM_WORLD);

// ...

std::vector<CELL> rbuf;
if (rank == 0)
    rbuf.resize(16);

MPI_Gather(partialGrid.data(), 4, mpi_cell, rbuf.data(), 4, mpi_cell, 0, MPI_COMM_WORLD);

For simplicity I hard-coded all the constants, too.

Upvotes: 5

Related Questions