MPI C ++ 인터페이스에서 사용자에게 필요한 기능은 무엇입니까?


28

MPI 표준 3.0 버전은 공식적으로 C ++ 인터페이스를 삭제했습니다 (이전에는 더 이상 사용되지 않음). 구현에서 여전히 지원할 수 있지만 MPI-3의 새로운 기능에는 MPI 표준에 정의 된 C ++ 인터페이스가 없습니다. 자세한 내용은 http://blogs.cisco.com/performance/the-mpi-c-bindings-what-happened-and-why/ 를 참조하십시오.

MPI에서 C ++ 인터페이스를 제거하려는 동기는 C 인터페이스보다 중요한 가치가 없다는 것이 었습니다. "s / _ / :: / g"이외의 차이점은 거의 없었으며 C ++ 사용자에게 익숙하지 않은 많은 기능 (예 : 템플릿을 통한 자동 유형 결정)이 사용되었습니다.

MPI 포럼에 참여하고 MPI C 함수에 대한 자체 C ++ 인터페이스를 구현 한 많은 C ++ 프로젝트와 협력하는 사람으로서 MPI에 대한 C ++ 인터페이스의 바람직한 기능이 무엇인지 알고 싶습니다. 나는 아무것도 약속하지 않지만 많은 사용자의 요구를 충족시키는 독립형 MPI C ++ 인터페이스의 구현을 보는 데 관심이 있습니다.

그리고 예, Boost :: MPI ( http://www.boost.org/doc/libs/1_54_0/doc/html/mpi.html )에 익숙 하지만 MPI-1 기능 만 지원하며 직렬화 모델은 다음과 같습니다. RMA를 지원하기가 매우 어렵습니다.

내가 좋아하는 MPI에 대한 하나의 C ++ 인터페이스는 Elemental ( https://github.com/poulson/Elemental/blob/master/src/core/imports/mpi.cpp ) 인터페이스 이므로 사람들은 다음과 같은 이점을 제공 할 수 있습니다. 접근. 특히 MpiMap이 필수 문제를 해결한다고 생각합니다.


나는 이것이 그러한 질문에 적합한 장소라고 생각하지 않습니다.
잭 폴슨

그것에 대한 몇 가지 이유를 줄 수 있습니까? 이 사이트의 많은 MPI 질문은 여기 사람들이이 질문에 대답 할 준비가되어 있다고 나에게 제안합니다. 또한 분당 0.2 upvotes는 다른 사람들이 귀하의 평가에 동의하지 않음을 나타냅니다. 어쨌든 현재 장소가 마음에 들지 않으면 이것을 게시 할 다른 장소를 제안하는 것이 더 도움이됩니다.
Jeff

질문은 귀중한 것이며, 범위가 넓다면 더 넓은 계산 과학 메일 링리스트에 대한 귀중한 응답을 얻을 수 있다고 생각합니다. (NA-digest, SIAM-CSE 또는 G +의 공개 게시물일까요?)이 질문은 주관적이므로 Stack Exchange 사이트에 적합하지 않을 수 있습니다 ( scicomp.stackexchange.com/help/dont-ask 참조 ) . 답변이 구체적이고 특정 사용 사례에 중점을 두는 한 (중복 반복 또는 겹침 없음) 공개적으로 유지하는 것이 좋습니다.
Geoff Oxberry

@ 제프 : 질문은 나에게 여론 조사와 매우 유사합니다. 나는 그것이 가치 있다고 주장하지는 않지만 하나의 대답이 받아 들여지는 것을 보지 못한다. MPI 포럼에서 그러한 질문이 평범하지 않습니까?
Jack Poulson

@JackPoulson 구현자가 옳은 답이라고 생각하는 것을 알고 싶지 않습니다. 전산 과학자들이 필요로하는 것을 알고 싶습니다. 이와 관련하여 질문에는 객관적인 답변이 있습니다. 정답은 없지만 주관적인 상황을 의미하지는 않습니다.
Jeff

답변:


17

MPI에 대한 C ++ 인터페이스가 일반적으로 과도하게 성공하지 못했다고 생각하는 이유에 대해 먼저 대답하겠습니다. MPI의 표준 C 바인딩을 사용해야하는지 또는 더 높은 수준의 무언가를 빌드해야하는지 결정하려고 할 때 오랫동안 문제에 대해 생각해 보았습니다. :

실제 MPI 코드 (예 : PETSc 또는 필자의 경우 거래 II)를 보면 놀랍게도 MPI 호출 수가 실제로 크지 않다는 것을 알 수 있습니다. 예를 들어, 500k 라인의 거래 II에는 ~ 100 개의 MPI 호출 만 있습니다. 그 결과 MPI C 바인딩과 같은 하위 수준 인터페이스를 사용하는 데 따르는 고통이 너무 크지 않습니다. 반대로, 더 높은 수준의 인터페이스를 사용하여 그다지 많은 것을 얻지 못할 것입니다.

두 번째 관찰은 많은 시스템에 여러 MPI 라이브러리 (다른 MPI 구현 또는 다른 버전)가 설치되어 있다는 것입니다. 헤더 파일만으로 구성되지 않은 boost :: mpi를 사용하려면이 패키지를 여러 개 설치해야하거나 패키지의 일부로 빌드해야하는 경우 상당한 어려움이 있습니다. boost :: mpi를 사용하는 프로젝트 (그러나 그 부스트는 다른 빌드 시스템과 달리 자체 빌드 시스템을 사용한다는 점에서 다시 문제가됩니다).

따라서이 모든 것이 MPI에 대한 현재 C ++ 인터페이스의 작물과 충돌 한 것으로 생각됩니다. 이전 MPI C ++ 바인딩은 이점을 제공하지 않았으며 외부 패키지는 현실 세계에 어려움이있었습니다.

이 모든 것은 다음과 같습니다. 높은 수준의 인터페이스에서 갖고 싶은 킬러 기능은 다음과 같습니다.

  • 일반적이어야합니다. 변수의 데이터 유형을 지정하는 것은 C ++과 유사하지 않습니다. 물론 오류도 발생합니다. Elemental의 MpiMap 클래스는 이미 훌륭한 첫 단계입니다 ( MpiMap::type변수가 정적 const가 아닌 이유 를 알 수 없으므로 객체를 만들지 않고 액세스 할 수 있습니다).

  • 임의의 데이터 유형을 스트리밍 할 수있는 기능이 있어야합니다.

  • MPI_Op인수 (예 : 축소)가 필요한 연산은 C ++의 std::function인터페이스 와 잘 통합되어야 하므로 무언가를 서투르게 등록하지 않고 함수 포인터 (또는 람다!)를 전달하기가 쉽습니다.

boost :: mpi는 실제로이 모든 것을 만족시킵니다. 헤더 전용 라이브러리라면 실제로 훨씬 더 인기가 있다고 생각합니다. MPI 1.0 이후의 기능을 지원한다면 도움이 될 것입니다. 그러나 솔직히 말하면, 이것은 대부분의 시간이 필요한 부분을 다룹니다.


Boost :: MPI의 직렬화 문제 중 하나는 일방적 (일명 RMA)에서 작동하지 않는다는 것입니다. 사용자가 관심이있는 C ++ 오브젝트에 대해 MPI 데이터 유형을 작성할 수 있다고 생각하십니까? 물론 이론적으로 모든 것이 지원되어야하지만 더 실용적인 목표로 시작하는 것을 선호합니다.
Jeff

직렬화 된 데이터 유형이 단방향 통신에서 작동 할 수 있다고 생각하는 것은 실수라고 생각합니다. 직렬화는 데이터를 문자열로 포장하고 다른 쪽에서는 다시 포장을 풀어야한다는 견해를 가정합니다. 그러나 직렬화 함수는 대상 호스트에서 아무것도 실행할 수없는 경우 작동 할 것으로 예상되는 것보다 훨씬 많은 작업을 수행 할 수 있습니다 (예 : 다른 객체에 대한 포인터 추적, 직렬화 된 바이트 수 등). 필자는 C ++ 스타일의 직렬화와 일방적 인 커뮤니케이션은 단순히 시작이 아니라는 것입니다. 아무도 이것이 효과가 있다고 기 대해서는 안되므로 그리워하지 않을 것입니다.
Wolfgang Bangerth

볼프강 안녕하세요, 정적 const 멤버 변수를 사용하면 MpiMap이 더 우아 할 것입니다. 구현을 재구성했습니다 : github.com/poulson/Elemental/commit/…
Jack Poulson

예, 훨씬 더
좋습니다

많지 않은 mpi 호출 @WolfgangBangerth에 대해 +1 기본적으로 mpi는 계산 속도를 높여야합니다. 비용이 많이 들기 때문에 mpi 호출을 최소화하고 싶습니다!
Charles Charles

6

볼을 굴리려면 다음 두 가지가 필요합니다.

  • 인터페이스는 중복되거나 불필요한 인수를 제거 할 수 있어야합니다 (예 : MPI_IN_PLACE).
  • 인터페이스는 Elemental의 MpiMap과 같은 내장 데이터 유형을 자동 감지해야합니다.
  • 가능하면 가능하면 클래스에 대해 사용자 정의 데이터 유형을 구성해야합니다.

5

특별한 선호 순서가없는 나의 목록. 인터페이스는 다음과 같아야합니다.

  • 의존성이없는 <mpi.h>표준 헤더 및 표준 라이브러리
  • 일반적이고 확장 가능해야합니다.
  • 비 차단 만 가능 ( 차단 하려는 경우 기본적으로 명시 적이 아닌 명시 적으로 차단)
  • 비 차단 작업의 연속 기반 체인을 허용합니다.
  • 확장 가능하고 효율적인 직렬화 (Boost.Fusion과 같은 RMA와 함께 작동) 지원
  • 추상화 불이익이 없습니다 (즉, C 인터페이스만큼 빠름).
  • 안전해야합니다 (준비되지 않은 미래의 소멸자는?-> std :: terminate!).,
  • DEBUG수많은 명제를 가진 강력한 모드
  • 매우 유형 안전합니다 (더 이상 int / void *가 없으며 태그를 유형으로 만들고 싶습니다!),
  • 람다와 함께 작동해야합니다 (예 : 모두 reduce + lambda).
  • 오류보고 및 오류 처리 메커니즘으로 예외를 일관되게 사용합니다 (더 이상 오류 코드가 없으며 더 이상 함수 출력 인수가 없음).
  • MPI-IO는 Boost.AFIO 스타일의 비 차단 I / O 인터페이스를 제공해야합니다.
  • 그리고 현대적인 C ++ 인터페이스 디자인 관행을 따르십시오 (정규 유형 정의, 비회원 비 친구 기능, 이동 의미론과 잘 작동, 범위 작업 지원 ...)

추가 사항 :

  • MPI 환경의 실행 프로그램, 즉 사용하는 스레드 풀을 선택할 수 있습니다. 지금은 OpenMP, MPI, CUDA 및 TBB가 혼합 된 응용 프로그램을 동시에 실행할 수 있습니다. 각 런타임은 환경을 소유한다고 생각하여 운영 체제에 느낌이들 때마다 스레드를 요청합니다. 그것. 진심이야?

  • STL (및 Boost) 명명 규칙을 사용하십시오. 왜? 모든 C ++ 프로그래머는 그것을 알고 있습니다.

다음과 같은 코드를 작성하고 싶습니다.

auto buffer = some_t{no_ranks};
auto future = gather(comm, root(comm), my_offsets, buffer)
              .then([&](){
                /* when the gather is finished, this lambda will 
                   execute at the root node, and perform an expensive operation
                   there asynchronously (compute data required for load 
                   redistribution) whose result is broadcasted to the rest 
                   of the communicator */
                return broadcast(comm, root(comm), buffer);
              }).then([&]() {
                /* when broadcast is finished, this lambda executes 
                   on all processes in the communicator, performing an expensive
                   operation asynchronously (redistribute the load, 
                   maybe using non-blocking point-to-point communication) */
                 return do_something_with(buffer);
              }).then([&](auto result) {
                 /* finally perform a reduction on the result to check
                    everything went fine */
                 return all_reduce(comm, root(comm), result, 
                                  [](auto acc, auto v) { return acc && v; }); 
              }).then([&](auto result) {
                  /* check the result at every process */
                  if (result) { return; /* we are done */ }
                  else {
                    root_only([](){ write_some_error_log(); });
                    throw some_exception;
                  }
              });

/* Here nothing has happened yet! */

/* ... lots and lots of unrelated code that can execute concurrently 
   and overlaps with communication ... */

/* When we now call future.get() we will block 
   on the whole chain (which might have finished by then!).
*/

future.get();

MPI_C를 사용하여이 모든 작업을 어떻게 연결할 수 있는지 생각해보십시오 request. 여러 관련되지 않은 코드를 통해 여러 (또는 모든 단일) 중간 단계에서 테스트하여 차단하지 않고 체인 진행할 수 있는지 확인해야합니다 .


이것은 요구 사항의 강렬한 목록입니다. 이들 중 일부는 모든 실용적인 목적으로 불가능합니다 (예 : 람다 감소 지원). 그러나 전반적으로 MPI 커뮤니티가 지원하고자하는 유형이라고 생각합니다.
Jeff

스레드 및 런타임 환경과 관련하여 MPI는 내부적으로 스레드 또는 OS 스레드 (OS에 따라 POSIX, Windows 또는 Solaris)를 사용합니다. 여기에서 요구 사항을 이해하고 있는지 잘 모르겠습니다.
Jeff

문제는 MPI가 운영 체제에서 임의의 스레드를 요청할 수 있다는 것입니다. 내 응용 프로그램에는 스레드 풀이 있으며 MPI가 스레드 풀에서 해당 스레드를 요청하고 싶습니다. OpenMP, TBB 및 MPI를 사용하는 응용 프로그램 (각각 자체 스레드 풀이 있고 각각 4x 수의 코어가있는 응용 프로그램)이없는 한 현재 불가능합니다.
gnzlbg

1
MPI는 일반적으로 내부적으로 OS 스레드를 사용할 수 없습니다. 내가 익숙한 모든 경우 (MPICH (2), MVAPICH2, OpenMPI, CrayMPI)에서 사용자가 제공 한 런타임 옵션 만이 문제가 발생합니다. 즉 기본값은 그렇지 않습니다. Blue Gene / Q MPI는 예외이지만이 논의와 관련이없는 형식입니다.
Jeff

감사합니다 @ Jeff! 단일 스레드를 사용하는 동안 MPI가 여러 비 차단 호출을 처리하는 방법에 대해 자세히 설명해 주시겠습니까? 코 루틴 / 녹색 실 / 섬유를 사용합니까?
gnzlbg

2

개인적으로 볼프강이 언급 한 바로 그 이유 때문에 긴 C 스타일 함수를 호출하는 것은 마음에 들지 않습니다. 실제로 호출해야 할 곳이 거의 없으며 심지어는 항상 상위 코드로 둘러싸여 있습니다.

C 스타일 MPI에서 실제로 나를 괴롭히는 유일한 것은 사용자 지정 데이터 형식이며, 사용자 지정 작업은 덜 사용하기 때문입니다. 사용자 정의 데이터 유형의 경우 좋은 C ++ 인터페이스가 직렬화를 통해 일반적이고 효율적인 처리 방법을 지원할 수 있어야한다고 말하고 싶습니다. 이것은 물론 boost.mpi당신이 조심 한다면 길을 잃은 경로입니다 .

에 관해서는 boost.mpi(특히 추가 종속성을 가지고 boost.serialization있는 자체가되지 헤더 전용), 최근 헤더 전용 C ++ 직렬화 라이브러리라는 건너 온 한 시리얼 약속하는 것; C ++ 11 호환 컴파일러가 필요합니다. 그것과 비슷한 것을 찾고 기반으로 사용하는 것이 boost.mpi좋습니다.


필자가 MPI 표준에 넣을 무언가를 반드시 찾지는 않았습니다. 나는 MPI가 거의 항상 "일부 고급 코드로 감싸 져야"한다는 것에 전적으로 동의합니다. 따라서 궁금한 점은 무엇입니까? Elemental은 훌륭한 접근 방식을 가지고 있지만 모든 경우에 가장 적합합니까? 매우 많은 사람들을 행복하게하려는 MPI에 대한 C ++ 인터페이스를 원한다면 어떤 모습일까요?
Jeff

@ 제프. 나를 위해 : 1. 나는 쉽게 사용자 정의 데이터 형식을 보낼 수 있기를 원합니다. 2. 사용자 지정 작업으로 쉽게 축소를 수행 할 수 있기를 바랍니다. 또한 나는 1이 2보다 더 중요하고 유용하다고 생각합니다.
GradGuy

C ++이 어떻게 마술 wrt (2)를 수행하는지 알 수 없습니다. 여기서 무엇을 상상하십니까?
Jeff

@Jeff 나는 thrust줄어드는 방법을 따라 뭔가를 생각하고 있었다 : docs.thrust.googlecode.com/hg/group__reductions.html
GradGuy

-1

github 프로젝트 easyLambda 는 C ++ 14와 함께 MPI에 대한 높은 수준의 인터페이스를 제공합니다.

나는 프로젝트가 비슷한 목표를 가지고 있다고 생각하고 현대 C ++을 사용 하여이 분야에서 수행 할 수 있고 수행중인 일에 대한 아이디어를 줄 것입니다. easyLambda 자체뿐만 아니라 다른 노력을 안내합니다.

성능 및 코드 라인에 대한 초기 벤치 마크 는 유망한 결과를 보여주었습니다.

여기에 이미지 설명을 입력하십시오

다음은 제공되는 기능 및 인터페이스에 대한 간단한 설명입니다.

이 인터페이스는 고유 한 병렬 처리를 제공하는 데이터 흐름 프로그래밍 및 기능 목록 작업을 기반으로합니다. 병렬 처리는 작업의 속성으로 표현됩니다. .prll () 속성을 사용하여 작업에 대한 프로세스 할당 및 데이터 배포를 요청할 수 있습니다. 의 예 좋은 수있다 웹 페이지코드 저장소 문서에서 설명하는 열 확산 문제를 일례로서 분자 역학을 후 처리, 열 방정식에 명시 유한 차분 용액 회귀 등 LAMMPS 포함 HPC 죽어된다 .. ~ 20 줄의 코드로 표현할 수 있습니다.

여기에 자세한 내용과 예제 코드를 추가하는 대신 링크를 제공하는 것이 좋습니다.

공개 자 : 저는 도서관의 저자입니다. easyLambda 및 이와 유사한 목표를 추구하는 다른 프로젝트에 유리할 수있는 easyLambda의 현재 인터페이스에 대해 건설적인 피드백을 받기를 기대하면서 아무런 해를 끼치 지 않는다고 생각합니다.


" 우리는 약간의 설명과 맥락을 제공하는 긴 답변을 찾고 있습니다. 단 한 번의 답변 만 제공하지 말고 답변이 이상적이고 인용에 적합한 이유를 설명하십시오. 설명이 포함되지 않은 답변은 제거 될 수 있습니다 . ". 왜 당신의 대답이이 설명에 적합 할만큼 완전하다고 생각합니까?
nicoguaro

OP가 요구하는 것과 유사한 인터페이스를 제공하는 프로젝트를 가리키고 있습니다. 답변 자체에서 프로젝트의 동기 부여 및 기능에 대한 세부 정보를 제공하고 OP 및 다른 사람들이 프로젝트에 대한 의견을 읽고 제안하도록 할 수 있습니다. 그러나 링크 만 제공하기로 결정했습니다. 나는 당신의 요점을 얻는다. 답변에 대한 참조가 포함 된 텍스트를 추가하겠습니다.
Utkarsh Bhardwaj

@ UtkarshBhardwaj : 일부 의견 : (1) C ++과 MPI를 인터페이스하는 라이브러리를 작성해 주셔서 감사합니다. 그것은 중요한 사업이며 많은 노력을 기울인 것처럼 보입니다. (2) 문서를 빨리 ​​(다시, 좋은 일로) 숙달하면 눈에 띄는 것은 사용 된 긴 일련의 메소드 명령 체인이며, 형식화되어 있어도 스타일 적으로 ... 디버그하기에 고통 스럽습니다. (3) 추상화는 맵 축소와 같은 작업에 유용하게 보이는 기능적 패러다임을 가정하지만 MPI로 프로그래밍하는 사람은 알고리즘을 다시 작업하고 알고있는 인터페이스에서 너무 멀리 나가고 싶지 않습니다.
제프 옥스 베리

(4) 예제의 어느 곳에서도 커뮤니케이터가 보이지 않으므로 모든 것에 MPI_COMM_WORLD를 사용하고 있다고 의심되어 라이브러리의 잠재력을 제한합니다. (5) 추상화는 MPI 추상화를 기반으로하며 다른 백엔드를 가질 수 있습니다. (6) (3)-(5)에 근거하여,이 라이브러리가 MPI 인터페이스라고 생각하지 않으며 결과적으로이 주석이 주제에 맞지 않다고 생각합니다.
Geoff Oxberry

귀중한 의견을 보내 주셔서 감사합니다. 특정 포인트에 대한 답장 : 2) 체인을 때로는 ExpressionBuilder 라고합니다 . 구성을 기능적 스타일로 표현하는 일반적인 방법입니다. 이 스타일로 ezl로 쓸 필요는 없습니다. 먼저 개별 단위를 작성한 다음 작성하고 [example] ( goo.gl/YzaL0k )을 확인하십시오 . 3) 제어 흐름 및 명령에서 데이터 흐름 및 기능으로 전환하기가 어렵다는 것을 알고 있습니다. 각각 장단점이 있습니다. 그러나, 나는 그 진정한 효능을 알기 위해 후자를 더 많이 탐구해야한다고 생각합니다.
Utkarsh Bhardwaj
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.