2016-08-10 2 views
1

Я хочу запустить область многопоточности OpenMP в одном процессе в моем коде приложения MPI. Например:Как запустить многопоточность в MPI + openmp?

#include <iostream> 
#include <omp.h> 
#include <mpi.h> 
#include <Eigen/Dense> 
using std::cin; 
using std::cout; 
using std::endl; 

using namespace Eigen; 

int main(int argc, char ** argv) 
{ 
    int rank, num_process; 
    MatrixXd A = MatrixXd::Ones(8, 4); 
    MatrixXd B = MatrixXd::Zero(8, 4); 
    MPI_Init(&argc, &argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &num_process); 
    MPI_Status status; 
    if (rank == 0) 
    { 
     int i, j, bnum = 2, brow = 4, thid; 
     #pragma omp parallel shared(A, B) private(i, j, brow, bnum, thid) num_threads(2) 
     for (i = 0; i < brow; i ++) 
     { 
      for (j = 0; j < 4; j ++) 
      { 
       thid = omp_get_thread_num(); 
       //cout << "thid " << thid << endl; 
       B(thid * brow+i,j) = A(thid*brow+i, j); 
      } 
     } 
     cout << "IN rank 0" << endl; 
     cout << B << endl; 
     cout << "IN rank 0" << endl; 
     MPI_Send(B.data(), 32, MPI_DOUBLE, 1, 1, MPI_COMM_WORLD); 
    } 
    else 
    { 
     MPI_Recv(B.data(), 32, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, &status); 
     cout << "IN rank 1" << endl; 
     cout << B << endl; 
     cout << "IN rank 1" << endl; 
    } 
    MPI_Finalize(); 
    return 0; 
} 

В моем примере кода, я хочу, чтобы запустить 2 темы для копирования данных из матрицы А на матрицу В, и моя машина имеет 4 ядра. Но при запуске программы матрица B получает только половину данных.

$ mpirun -n 2 ./shareMem 
IN rank 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
IN rank 0 
IN rank 1 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
IN rank 1 

$ mpirun -n 4 ./shareMem # it just hang on and doesn't exit 
IN rank 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
IN rank 0 
IN rank 1 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0 
IN rank 1 

И выход я ожидал это

$ mpirun -n 2 ./shareMem # it just hang on and doesn't exit 
IN rank 0 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
IN rank 0 
IN rank 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
1 1 1 1 
IN rank 1 

Как я могу это исправить и сделать 2 нити работать в моем коде? Спасибо!

+0

Пожалуйста, предоставьте нам пример [MCVE] (http://stackoverflow.com/help/mcve), чтобы помочь вам лучше. Например, MatrixXd не определяется нигде. Кроме того, какой ожидаемый результат вы хотите? Чем он отличается от того, что вы получаете? И как вы знаете, что 2 потока не работают? – Harald

+0

@Harald, MatrixXd из файла include , это матричный класс. Я отредактировал вопрос –

+0

Извините Alexander, но откуда этот заголовок? Например, у меня его нет в моей системе. – Harald

ответ

1

Смените

#pragma omp parallel shared(A, B) private(i, j, brow, bnum, thid) num_threads(2) 

в

#pragma omp parallel shared(A, B) private(i, j, thid) num_threads(2) 

brow, bnum являются общими переменными. Добавляя имена bnum и brow в частное предложение, вы создаете новые автоматические переменные с такими именами для каждого потока, и по умолчанию они не определены.

1

В слове параллельна опечатка, которую компилятор не поймает.

#pragma omp prallel

PS: Я не хватает репутации, чтобы добавить комментарий

+0

спасибо, но после того, как она была изменена на 'parallel', я даже получил все нули? Что не так с моим кодом? –

Смежные вопросы