하이퍼 큐브 그룹에 속한 프로세스간에 값을 분산하려고합니다 (quicksort 프로젝트). 프로세스의 양에 따라 과도한 프로세스를 제외하고 새로운 커뮤니케이터를 생성하거나 정확하게 하이퍼 큐브 (2의 거듭 제곱)에 맞는 MPI_COMM_WORLD를 복제합니다. 두 경우MPI_Scatterv : 프로세스 0의 분할 오류 11
, 데이터를 수신 0 이외 처리하지만 : - 첫 번째 시나리오에서, 프로세스 0 세그멘테이션 오류 11 슬로우 - 번째 시나리오 아무것도 결함 온하지만 프로세스 0 값 무의미한이다 받았다.
참고 : 일반 MPI_Scatter를 시도하면 모든 것이 잘 작동합니다. 우선
//Input
vector<int> LoadFromFile();
int d; //dimension of hypercube
int p; //active processes
int idle; //idle processes
vector<int> values; //values loaded
int arraySize; //number of total values to distribute
int main(int argc, char* argv[])
{
int mpiWorldRank;
int mpiWorldSize;
int mpiRank;
int mpiSize;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &mpiWorldRank);
MPI_Comm_size(MPI_COMM_WORLD, &mpiWorldSize);
MPI_Comm MPI_COMM_HYPERCUBE;
d = log2(mpiWorldSize);
p = pow(2, d); //Number of processes belonging to the hypercube
idle = mpiWorldSize - p; //number of processes in excess
int toExclude[idle]; //array of idle processes to exclude from communicator
int sendCounts[p]; //array of values sizes to be sent to processes
//
int i = 0;
while (i < idle)
{
toExclude[i] = mpiWorldSize - 1 - i;
++i;
}
//CREATING HYPERCUBE GROUP: Group of size of power of 2 -----------------
MPI_Group world_group;
MPI_Comm_group(MPI_COMM_WORLD, &world_group);
// Remove excessive processors if any from communicator
if (idle > 0)
{
MPI_Group newGroup;
MPI_Group_excl(world_group, 1, toExclude, &newGroup);
MPI_Comm_create(MPI_COMM_WORLD, newGroup, &MPI_COMM_HYPERCUBE);
//Abort any processor not part of the hypercube.
if (mpiWorldRank > p)
{
cout << "aborting: " << mpiWorldRank <<endl;
MPI_Finalize();
return 0;
}
}
else
{
MPI_Comm_dup(MPI_COMM_WORLD, &MPI_COMM_HYPERCUBE);
}
MPI_Comm_rank(MPI_COMM_HYPERCUBE, &mpiRank);
MPI_Comm_size(MPI_COMM_HYPERCUBE, &mpiSize);
//END OF: CREATING HYPERCUBE GROUP --------------------------
if (mpiRank == 0)
{
//STEP1: Read input
values = LoadFromFile();
arraySize = values.size();
}
//Transforming input vector into an array
int valuesArray[values.size()];
if(mpiRank == 0)
{
copy(values.begin(), values.end(), valuesArray);
}
//Broadcast input size to all processes
MPI_Bcast(&arraySize, 1, MPI_INT, 0, MPI_COMM_HYPERCUBE);
//MPI_Scatterv: determining size of arrays to be received and displacement
int nmin = arraySize/p;
int remainingData = arraySize % p;
int displs[p];
int recvCount;
int k = 0;
for (i=0; i<p; i++)
{
sendCounts[i] = i < remainingData
? nmin+1
: nmin;
displs[i] = k;
k += sendCounts[i];
}
recvCount = sendCounts[mpiRank];
int recvValues[recvCount];
//Following MPI_Scatter works well:
// MPI_Scatter(&valuesArray, 13, MPI_INT, recvValues , 13, MPI_INT, 0, MPI_COMM_HYPERCUBE);
MPI_Scatterv(&valuesArray, sendCounts, displs, MPI_INT, recvValues , recvCount, MPI_INT, 0, MPI_COMM_HYPERCUBE);
int j = 0;
while (j < recvCount)
{
cout << "rank " << mpiRank << " received: " << recvValues[j] << endl;
++j;
}
MPI_Finalize();
return 0;
}
내가 검사 오류를 추가 :
std::vector<T>
그러므로 정기적 배열에 요소를 복사하지 않고 할 수있는 간단MPI_Scatter(v)
에 대한 호출의 첫 번째 요소의 주소를 제공, 연속 된 저장소를 사용 실패 할 수있는 모든 작업과 많은 디버그 출력 (printf 또는 이와 유사한) 값이 예상되는 것이 아니거나 연산이 실패 할 경우 오버플로 될 수있는 배열이 많이 있습니다. 다중 프로세스를 사용하면 코드를 수동으로 읽음으로써 디버그를 훨씬 더 어렵게하거나 불가능하게 만들 수 있습니다. – uesp