MPI, openMP 및이 둘의 조합으로 문제를 해결하려고합니다. MPI와 openMP가 모두 잘 실행되고 있지만 MPI-openMP 버전의 코드를 시도하면 게시물 끝에 오류가 표시됩니다.
for(i=0;i<loop;i++)
{
for(j=start;j<end+1;j++)
{
for(k=0;k<N;k++)
{
if(j!=k)
{
dx=C[k*3+0]-C[j*3+0];
dy=C[k*3+1]-C[j*3+1];
dz=C[k*3+2]-C[j*3+2];
d=sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2));
dCube=pow(d,3);
mSquare=pow(m,2);
F[(j-start)*3+0]-=G*mSquare/dCube*dx;
F[(j-start)*3+1]-=G*mSquare/dCube*dy;
F[(j-start)*3+2]-=G*mSquare/dCube*dz;
}
}
}
for(j=0;j<length;j++)
{
for(k=0;k<3;k++)
{
a=F[j*3+k]/m;
V[j*3+k]=V[j*3+k]+a*dt;
Cw[j*3+k]=C[(j+start)*3+k]+V[j*3+k]*dt;
}
}
MPI_Allgatherv(&Cw[0],length*3,MPI_DOUBLE,&C[0],counts,displs,MPI_DOUBLE,MPI_COMM_WORLD);
}
loop
: 프로세스가 수행 될 금액을 설명합니다.C
권리를위한 테이블이 필요 구멍이 초래 start
& end
변수는 테이블의 모든 노드 마녀 부분에 대한 책임이 있습니다에게MPI_allgather
끝에 새로운 이전의 CW 테이블에 저장되어있는 새 값으로 C 테이블을 업데이트 i
루프 시작counts
변수는 데이터의 크기 MPI_Allgather
로 전송되고이 displs
마녀 위치에 C
놓음해야 모든 노드 Cw
데이터#pragma omp parallel private(i,k,dx,dy,dz,d,dCube,mSquare,a)
{
for(i=0;i<loop;i++)
{
#pragma omp for schedule(static)
for(j=0;j<N;j++)
{
for(k=0;k<N;k++)
{
if(j!=k)
{
dx=C[k*3+0]-C[j*3+0];
dy=C[k*3+1]-C[j*3+1];
dz=C[k*3+2]-C[j*3+2];
d=sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2));
dCube=pow(d,3);
mSquare=pow(m,2);
F[j*3+0]-=G*mSquare/dCube*dx;
F[j*3+1]-=G*mSquare/dCube*dy;
F[j*3+2]-=G*mSquare/dCube*dz;
}
}
}
#pragma omp for schedule(static)
for(j=0;j<N;j++)
{
for(k=0;k<3;k++)
{
a=F[j*3+k]/m;
V[j*3+k]=V[j*3+k]+a*dt;
C[j*3+k]=C[j*3+k]+V[j*3+k]*dt;
}
}
}
}
i
루프 때문에 업데이트의 필요성을 평행하게 할 수 C
로부터의 평행 한 부분이 시작되도록 각 루프j
#pragma omp parallel private(i,k,dx,dy,dz,d,dCube,mSquare,a)
{
for(i=0;i<loop;i++)
{
#pragma omp for schedule(static)
for(j=start;j<end+1;j++)
{
for(k=0;k<N;k++)
{
if(j!=k)
{
dx=C[k*3+0]-C[j*3+0];
dy=C[k*3+1]-C[j*3+1];
dz=C[k*3+2]-C[j*3+2];
d=sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2));
dCube=pow(d,3);
mSquare=pow(m,2);
F[(j-start)*3+0]-=G*mSquare/dCube*dx;
F[(j-start)*3+1]-=G*mSquare/dCube*dy;
F[(j-start)*3+2]-=G*mSquare/dCube*dz;
}
}
}
#pragma omp for schedule(static)
for(j=0;j<length;j++)
{
for(k=0;k<3;k++)
{
a=F[j*3+k]/m;
V[j*3+k]=V[j*3+k]+a*dt;
Cw[j*3+k]=C[(j+start)*3+k]+V[j*3+k]*dt;
}
}
MPI_Allgatherv(&Cw[0],length*3,MPI_DOUBLE,&C[0],counts,displs,MPI_DOUBLE,MPI_COMM_WORLD);
}
}
내가 여기서 달성하려고 시도한 것은 위의 MPI 접근 방식으로 작업 할 MPI
마녀 부분이있는 모든 노드에서 말한 C
다음 openMP Cw
가이 부분에 해당 하는 테이블을 계산하는 것 입니다. 그런 다음 MPI MPI_Allgather
는 C
테이블에 결과를 수집하고 loop
시간 동안 다시 시작합니다 . 문제는 위의 코드를 실행하면이 오류가 표시된다는 것입니다.
파일 src / mpid / ch3 / src / ch3u_request.c의 572 행에서 어설 션 실패 : * (& incomplete)> = 0
= 응용 프로그램 프로세스 중 하나의 잘못된 종료
= felix-desktop에서 실행중인 PID 10389
= 종료 코드 : 139
= 남은 프로세스 정리 = 아래 정리 메시지를 무시할
수 있습니다.애플리케이션이 종료 문자열로 종료 됨 : 세그멘테이션 오류 (신호 11)
일반적으로 애플리케이션의 문제를 나타냅니다.
디버깅 제안은 FAQ 페이지를 참조하십시오.
문제는 MPI_Allgather
코드 줄에 있지만 원인이 무엇인지 알 수 없습니다.
당신은 MPI_Allgather
내부를 평행 영역 이라고 부르고 있습니다. 따라서 해당 MPI
루틴은 표준에서 허용하지 않는 여러 스레드에 의해 동일한 커뮤니케이터 ( 예 :)를 사용하여 호출됩니다 . 그럼에도 불구하고 루틴이 단일 스레드에 의해 호출 되는지 확인할 수 있습니다 .MPI_COMM_WORLD
MPI
MPI_Allgather
#pragma omp parallel private(i,k,dx,dy,dz,d,dCube,mSquare,a)
{
...
#pragma omp master
MPI_Allgatherv(&Cw[0],length*3,MPI_DOUBLE,&C[0],counts,displs,MPI_DOUBLE,MPI_COMM_WORLD);
#pragma omp barrier
}
첨가 용으로 OpenMP
절을 master
하나의 스레드가 호출 한 보장하지만 MPI_Allgather
( 즉,master
스레드). 경쟁 조건 ( 즉,MPI_Allgatherv
MPI
호출에 사용될 콘텐츠를 변경하는 스레드) 이 없는지 확인하기 위해 OpenMP barrier
가 MPI_Allgather
. 따라서 모든 프로세스의 모든 master
스레드는 해당 프로세스 의 스레드가 MPI_Allgather
호출 수행을 마칠 때까지 대기 합니다.
사용중인 MPI 버전의 스레드 지원 수준이 MPI_THREAD_SERIALIZED 인 경우 single
대신 생성자 를 사용할 수 있습니다 master
. MPI 구현의 스레드 지원 수준이 최소한 MPI_THREAD_FUNNELED
.
또 다른 접근 방식은 MPI_Allgather
루틴을 병렬 영역 외부 로 이동하는 것입니다 .
for(i=0;i<loop;i++)
{
#pragma omp parallel private(i,k,dx,dy,dz,d,dCube,mSquare,a){
...
}
MPI_Allgatherv(&Cw[0],length*3,MPI_DOUBLE,&C[0],counts,displs,MPI_DOUBLE,MPI_COMM_WORLD);
}
다중 병렬 영역 생성 오버 헤드는 적절한 OpenMP 구현이 스레드 풀을 사용하므로 스레드를 한 번만 초기화 한다는 사실로 인해 감쇠되어야합니다 .
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다