2

MPI를 통해 함수 포인터를 전달하여 다른 노드가 함수를 호출하도록하는 것이 안전합니까? 누군가는 MPI를 통해 어떤 종류의 포인터를 전달하는 것은 의미가 없다고 말할 수 있습니다 만, 그것을 검증하기위한 코드를 작성했습니다. 여기 MPI를 통해 함수 포인터 보내기

//test.cpp 
#include <cstdio> 
#include <iostream> 
#include <mpi.h> 
#include <cstring> 

using namespace std; 

int f1(int a){return a + 1;} 
int f2(int a){return a + 2;} 
int f3(int a){return a + 3;} 

using F=int (*)(int); 

int main(int argc, char *argv[]){ 
    MPI_Init(&argc, &argv); 
    int rank, size; 
    MPI_Status state; 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    //test 
    char data[10]; 
    if(0 == rank){ 
     *(reinterpret_cast<F*>(data))=&f2; 
     for(int i = 1 ; i < size ; ++i) 
      MPI_Send(data, 8, MPI_CHAR, i, 0, MPI_COMM_WORLD); 
    }else{ 
     MPI_Recv(data, 8, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &state); 
     F* fp = reinterpret_cast<F*>(data); 
     int ans = (**fp)(10); 
     cout << ans << endl; 
    } 


    MPI_Finalize(); 
    return 0; 
} 

는 출력 :

12 
12 
12 
12 
12 
12 
12 
12 
12 

내가 MVAPICH를 통해 그것을 실행, 그리고 그것을 잘 작동합니다. 하지만 지금은 별개의 주소 공간은 포인터 값이을 생성 한 프로세스가 아닌 다른 프로세스에서 USELESS라는 것을 의미하기 때문에 필자는 그 이유가 없습니다.

P. 여기 내 hostfile

blade11:1 
blade12:1 
blade13:1 
blade14:1 
blade15:1 
blade16:1 
blade17:1 
blade18:2 
blade19:1 

내가 사용 mpiexec -n 10 -f hostfile ./test를 실행하고, 컴파일 된 C++ (11)

답변

7

당신은 당신의 클러스터 환경이 균일하고 일반 실행 파일에 대한 주소 공간 무작위가에없는 의미에서 운 장소. 결과적으로 모든 이미지는 동일한 기본 주소에로드되고 메모리에 비슷하게 배치됩니다. 따라서 함수는 모든 MPI 순위에서 동일한 가상 주소를 갖습니다 (동적로드 라이브러리에서 심볼이로드되는 경우는 거의 없습니다). 임의의 주소).

다른 컴파일러를 사용하거나 동일한 컴파일러를 사용하지만 다른 컴파일러 옵션을 사용하여 소스를 두 번 컴파일 한 경우 첫 번째 실행 파일을 실행하고 나머지는 두 번째 실행 파일을 실행하면 프로그램이 확실히 중단됩니다.

이 시도 : 다른 크기의 함수 코드의 최적화 결과의

$ mpicxx -std=c++11 -O0 -o test_O0 test.cpp 
$ mpicxx -std=c++11 -O2 -o test_O2 test.cpp 
$ mpiexec -f hostfile -n 5 ./test_O0 : -n 5 ./test_O2 
12 
12 
12 
12 
<crash> 

서로 다른 수준을 test_O0test_O2에. 결과적으로 f2은 더 이상 모든 순위에서 동일한 가상 주소를 갖지 않습니다. 순위 0과 동일한 실행 파일을 실행하는 순위는 12을 인쇄하고 나머지는 segfault를 인쇄합니다.

2

MPI를 통해 함수 포인터를 전달하면 다른 노드가 함수를 호출하도록하는 것이 안전합니까?

아니요, 아닙니다. 주소 공간은 프로세스간에 공유되지 않습니다. 특정 메시지가 수신되면

그러나, 동일한 소스로부터 내장 프로그램의 결과 MPI 프로세스는 특정 함수를 호출하도록 구성 될 수

char data = 0; 
MPI_Recv(data, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &state); 

if (data == 255) { 
    f2(10); /* and so forth */ 
}