2016-08-10 5 views
1

내 MPI 응용 프로그램 코드 내에서 한 프로세스에서 OpenMP 다중 스레드 영역을 시작하려고합니다. 예를 들어 : 내 예제 코드에서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; 
} 

, 나는 행렬 B를 행렬 A에서 데이터를 복사 할 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는 어디에도 정의되어 있지 않습니다. 또한 원하는 출력이 어느 것입니까? 당신이 얻는 것과 어떻게 다른가요? 두 스레드가 실행되고 있지 않다는 것을 어떻게 알 수 있습니까? – Harald

+0

@Harald, MatrixXd는 포함 파일 에서 가져온 것으로, 매트릭스 클래스입니다. 나는 –

+0

미안 알렉산더 질문을 편집했는데, 그 헤더는 어디에서 왔는가? 예를 들어 내 시스템에는이 기능이 없습니다. – Harald

답변

1

에게

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

bnum 공유 변수,

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

brow

에 추가하기에 충분한 명성을 필요가 없습니다. private 절에 bnumbrow이라는 이름을 추가하면 각 스레드에 대해 이러한 이름을 가진 새로운 자동 변수가 만들어지고 기본적으로 정의되지 않습니다.

1

컴파일러에서 catch하지 않는 parallel이라는 단어에 오타가 있습니다.

#pragma omp prallel

PS : 나는 변경에게 코멘트

+0

고맙습니다.하지만 '평행'으로 변경 한 후에도 모든 0이 붙었습니까? 내 코드에 어떤 문제가 있습니까? –

관련 문제