I want to store a 3-dimensional matrix in a way that all the data is contiguous. This is because I need to send the matrix to a master node using MPI, and then concantenate all the smaller matrices into one big matrix. This becomes cumbersome with a nested vector, since you can only send more than one int, double, etc. if they are contiguous in memory, so you have to send each of the innermost vectors separately, using something like
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
int id_of_data = i*ny*nz + j*nz;
MPI_Send(&local_matrix[i][j][0], nz, MPI_DOUBLE, 0, id_of_data, MPI_COMM_WORLD);
}
}
and then receive the data on the master node, using id_of_data
Right now I'm using std vectors for storing the matrix,
std::vector<std::vector<std::vector<double> > > matrix;
so I'm trying to stick to std::vector for now. I realize it's easy to solve this using arrays/pointers, but I want to try this using std::vectors before resorting to that. The dimensions of the matrix are constant, so I don't have to worry about dynamic allocation.
I can access the elements of the vector using pointers like this
double* a = &matrix[x][y][z];
but I don't know how to do "the opposite", ie. something like
double* vec_ptr = new float(nz);
&matrix[x][y][0] = vec_ptr;
What I would like to do is
double* linear_matrix = new double(nx*ny*nz);
and then somehow make the nested vectors point to this data.
I ended up creating my own classes for this kind of situations. It is very typical for matrix manipulation libraries to take a matrix as a contiguous block of data, but at the same time I would like to be able to fill and read it using the standard m[i][j] accessors. So, here you go. Below is the code to create containers in arbitrary dimensions as a contiguous block of memory. Using boost preprocessor here to be able to do any dimension. If you only need it up to 3d it is quite obvious to de-boostify it :)
memblock.h
memblock.cpp