Я пытаюсь использовать Eigen с многопоточностью в головном процессе программы MPI. Без MPI многопоточность Eigen прекрасно работает для умножения матрицы на матрицу.
При использовании MPI, инициализированного MPI_Init_thread (...), хотя Eigen :: nbThreads () возвращает правильное количество потоков, фактически только Eigen использует только один поток.
Пример кода:
#include "mpi.h"
#include "omp.h"
#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
using Eigen::VectorXd;
using namespace Eigen;
int main(int argc, char **argv)
{
int numprocs, rank;
int iam = 0, np = 1;
int threading = -1;
int nthreads = 8;
MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &threading);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
omp_set_num_threads(nthreads);
#pragma omp parallel default(shared) private(iam, np)
{
np = omp_get_num_threads();
iam = omp_get_thread_num();
std::cout << "Hello from thread " << iam << " out of " << np << " from process " << rank << " out of " << numprocs << std::endl;
}
std::cout << "Testing eigen multithreading ..." << std::endl;
Eigen::setNbThreads(nthreads);
Eigen::initParallel();
std::cout << "Eigen: number of threads: " << Eigen::nbThreads() << std::endl;
int flag;
MPI_Is_thread_main(& flag);
std::cout << "MPI_Is_thread_main: " << flag << std::endl;
if (rank==0)
{
int n = 5000;
MatrixXd A = MatrixXd::Ones(n,n);
MatrixXd B = MatrixXd::Ones(n,n);
MatrixXd C = MatrixXd::Ones(n,n);
C.noalias() += A*B;
std::cout << C.sum() << std::endl;
}
std::cout << "Testing eigen multithreading finished ..." << std::endl;
MPI_Finalize();
}
Компиляция: mpicxx -fopenmp hello.cpp -o hello -I./include
Выполнение: mpirun -np 1 ./hello
или mpirun -np 1 -x OMP_NUM_THREADS=8 ./hello
Вывод:
Hello from thread 0 out of 8 from process 0 out of 1
Hello from thread 7 out of 8 from process 0 out of 1
Hello from thread 6 out of 8 from process 0 out of 1
Hello from thread 5 out of 8 from process 0 out of 1
Hello from thread 4 out of 8 from process 0 out of 1
Hello from thread 3 out of 8 from process 0 out of 1
Hello from thread 2 out of 8 from process 0 out of 1
Hello from thread 1 out of 8 from process 0 out of 1
Testing eigen multithreading ...
Eigen: number of threads: 8
MPI_Is_thread_main: 1
...
Похоже, что гибридный режим MPI-OpenMP правильно работает за пределами собственной области. Я использую Eigen-3.3.7. Я пробовал openmpi-1.8.6 (ompi_info возвращает MPI_THREAD_MULTIPLE: да) и openmpi-4.0.2. Фактическое количество потоков можно проверить по загрузке ЦП.
Интересно, нужно ли мне что-то еще сделать, чтобы оно заработало, или по какой-то причине Eigen не поддерживает этот гибридный режим? Спасибо!