#include <cassert>
#include <cstdio>
#include <mpi.h>
#include <hpc/matvec/gematrix.h>
#include <hpc/mpi/matrix.h>
#include <hpc/mpi/vector.h>
#include <hpc/matvec/apply.h>
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
int nof_processes; MPI_Comm_size(MPI_COMM_WORLD, &nof_processes);
int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank);
assert(nof_processes == 2);
using namespace hpc::matvec;
using namespace hpc::mpi;
using namespace hpc::aux;
unsigned int nof_rows = 3;
unsigned int nof_cols = 7;
if (rank == 0) {
GeMatrix<double> A(nof_rows, nof_cols, StorageOrder::RowMajor);
using Index = GeMatrix<double>::Index;
apply(A, [](double& val, Index i, Index j) -> void {
val = i * 100 + j;
});
auto row = A.row(2);
auto col = A.col(0);
MPI_Datatype row_type = get_type(row);
MPI_Datatype col_type = get_type(col);
MPI_Send(&row(0), 1, row_type, 1, 0, MPI_COMM_WORLD);
MPI_Send(&col(0), 1, col_type, 1, 0, MPI_COMM_WORLD);
/* receive it back for verification */
DenseVector<double> vec1(nof_cols), vec2(nof_rows);
MPI_Datatype vec1_type = get_type(vec1);
MPI_Datatype vec2_type = get_type(vec2);
MPI_Status status;
MPI_Recv(&vec1(0), 1, vec1_type, 1, 0, MPI_COMM_WORLD, &status);
MPI_Recv(&vec2(0), 1, vec2_type, 1, 0, MPI_COMM_WORLD, &status);
/* verify it */
apply(vec1, [=](double& val, Index i) {
if (val != row(i)) {
printf("verification failed for row(%d): %lg vs %lg\n",
(int)i, val, row(i));
}
});
apply(vec2, [=](double& val, Index i) {
if (val != col(i)) {
printf("verification failed for col(%d): %lg vs %lg\n",
(int)i, val, col(i));
}
});
} else {
DenseVector<double> vec1(nof_cols), vec2(nof_rows);
MPI_Datatype vec1_type = get_type(vec1);
MPI_Datatype vec2_type = get_type(vec2);
MPI_Status status;
MPI_Recv(&vec1(0), 1, vec1_type, 0, 0, MPI_COMM_WORLD, &status);
MPI_Recv(&vec2(0), 1, vec2_type, 0, 0, MPI_COMM_WORLD, &status);
/* send it back for verification */
MPI_Send(&vec1(0), 1, vec1_type, 0, 0, MPI_COMM_WORLD);
MPI_Send(&vec2(0), 1, vec2_type, 0, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
}