Мне нужно передать матрицу или сложный тип матрицы, определенный Matrix Library Armadillo C++, через MPI. Каков хороший способ сделать это? Я думал попробовать:
Запишите матрицу в какой-нибудь массив, а затем отправьте
строки/столбцы этого массива с помощью методов для удаления/восстановления массивов по обе стороны отMPI_send
/recv
Используя что-то вроде типа
MPI_BYTE
?
Спасибо
Обновлять
Поэтому я пытался реализовать другую схему, отправляя и получая, для простого примера, на одном узле.
перевести.cpp
#include <mpi.h>
#include <armadillo>
#include <vector>
#include <cstdlib>
using namespace std;
using namespace arma;
using std::vector;
class ArmadilloMPI
{
public:
ArmadilloMPI(int nRows, int nCols)
{
this->nRows = nRows;
this->nCols = nCols;
realArray = (double **)malloc(nCols * nRows * sizeof(double*));
imArray = (double **)malloc(nCols * nRows * sizeof(double*));
}
~ArmadilloMPI()
{
free(realArray[0]);
free(realArray);
free(imArray[0]);
free(imArray);
}
double **realArray;
double **imArray;
int nCols;
int nRows;
cx_mat matConstructRecv(int src, int tag)
{
cx_mat A(nRows, nCols);
MPI_Recv(&(imArray[0][0]), nRows * nCols, MPI_DOUBLE, src, tag, MPI_COMM_WORLD,0);
MPI_Recv(&(realArray[0][0]),nRows * nCols, MPI_DOUBLE, src, tag, MPI_COMM_WORLD,0);
for(int i = 0; i < nRows; ++i )
{
for(int j = 0; i < nCols; ++j)
{
real(A(i,j)) = *realArray[i * nRows + j];
imag(A(i,j)) = *imArray[i * nRows + j];
}
}
return A;
}
void matDestroySend(cx_mat &A, int dest, int tag)
{
for(int i = 0; i < nRows; ++i )
{
for(int j = 0; i < nCols; ++j)
{
realArray[i * nRows + j] = &real(A(i,j));
imArray[i * nRows + j] = &imag(A(i,j));
}
}
MPI_Send(&(realArray[0][0]), nRows * nCols, MPI_DOUBLE, dest, tag, MPI_COMM_WORLD);
MPI_Send(&(imArray[0][0]), nRows * nCols, MPI_DOUBLE, dest, tag, MPI_COMM_WORLD);
}
};
int main(int argc, char** argv)
{
MPI::Init(argc, argv);
int size = MPI::COMM_WORLD.Get_size();
int rank = MPI::COMM_WORLD.Get_rank();
cout << "test"<<endl;
vector<cx_mat> world;
for(int i = 0; i < size; ++i )
{
world.push_back(randu<cx_mat>(4,4));
}
cx_mat A;
A = randu<cx_mat>(4,4);
ArmadilloMPI* armaMPI = new ArmadilloMPI(4,4);
if(rank==0)
{
for(int i = 1; i < size; i++)
{
cout << "A is now " << A << endl;
A += armaMPI->matConstructRecv(i, 0);
}
}
else
{
armaMPI->matDestroySend(world[rank], 1, 0);
}
cout << A << endl;
delete armaMPI;
MPI::Finalize();
}
Но у нас ошибка seg.
*** Process received signal ***
Signal: Segmentation fault: 11 (11)
Signal code: (0)
Failing at address: 0x0 translate(1032,0x7fff747ad310) malloc: *** error for object 0x41434d5f49504d4f: pointer being freed was not allocated
Мысли?
MPI_Bcast( &AAA(0,0), sizex*sizey*64, MPI_BYTE, 0, MPI_COMM_WORLD);
, и он вызывает ошибку сегментации, как толькоAAA
становится больше 16x16 или около того. Я бы выбрал первый вариант... Вас может заинтересовать ссылка MATMPIDENSE тип матрицы библиотеки PETSc. Здесь пример. - person francis   schedule 05.09.2014