我的排序程序可以在数组中偶数个元素上正常工作,但是会出现错误
“ MPI_Gather中的致命错误:消息被截断,错误堆栈:MPI_Gather(sbuf = 0x00A2A700,scount = 4,MPI_INT,rbuf = 0x00A302C8,rcount = 4,MPI_INT,root = 0,MPI_COMM_WORLD)失败,来自等级1和标记-1342177184 ;接收到28个字节,但缓冲区大小为16 “
对于数组中元素的奇数个。问题始于代码if ((world_rank == 1) && (n % world_size != 0))
。我尝试了一切,但没有成功。我怎样才能解决这个问题?提前致谢!
void merge(int*, int*, int, int, int);
void mergeSort(int*, int*, int, int);
int main(int argc, char** argv) {
int world_rank;
int world_size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int n = atoi(argv[1]);
int* original_array{ new int[n] {} };
//int original_array[]=new int[n];
int c;
srand(time(NULL));
if (world_rank == 0) {
printf("This is the unsorted array: ");
for (c = 0; c < n; c++) {
original_array[c] = rand() % n;
printf("%d ", original_array[c]);
}
printf("\n");
printf("\n");
}
int size = n / world_size;
int* sub_array=NULL;
int* tmp_array = NULL;
int* sorted = NULL;
if (world_rank == 0) {
sorted = { new int[n] {} };
}
if ((world_rank == 1) && (n % world_size != 0)) {
int r = n % world_size;
int size2 = size + r;
sub_array = { new int[size2] {} };
MPI_Scatter(original_array, size2, MPI_INT, sub_array, size2, MPI_INT, 0, MPI_COMM_WORLD);
tmp_array = { new int[size2] {} };
mergeSort(sub_array, tmp_array, 0, (size2 - 1));
MPI_Gather(sub_array, size2, MPI_INT, sorted, size2, MPI_INT, 0, MPI_COMM_WORLD);
}
else {
sub_array = { new int[size] {} };
MPI_Scatter(original_array, size, MPI_INT, sub_array, size, MPI_INT, 0, MPI_COMM_WORLD);
tmp_array = { new int[size] {} };
mergeSort(sub_array, tmp_array, 0, (size - 1));
MPI_Gather(sub_array, size, MPI_INT, sorted, size, MPI_INT, 0, MPI_COMM_WORLD);
}
if (world_rank == 0) {
printf("Array state before final mergeSort call: ");
for (c = 0; c < n; c++) {
printf("%d ", sorted[c]);
}
printf("\n");
int* other_array{ new int[n] {} };
mergeSort(sorted, other_array, 0, (n - 1));
printf("This is the sorted array: ");
for (c = 0; c < n; c++) {
printf("%d ", sorted[c]);
}
printf("\n");
printf("\n");
delete[] sorted;
delete[] other_array;
}
delete[] original_array;
delete[] sub_array;
delete[] tmp_array;
/********** Finalize MPI **********/
MPI_Finalize();
}
TL; DR:使用偶数个元素调用流程MPI_Scatter
,MPI_Gather
使用相同的元素调用,count
而不使用奇数元素。
我的排序程序在数组中偶数个元素上都能正常工作
当数组大小为偶数时,所有进程都将执行以下else
部分:
if ((world_rank == 1) && (n % world_size != 0)) {
int r = n % world_size;
int size2 = size + r;
sub_array = { new int[size2] {} };
MPI_Scatter(original_array, size2, MPI_INT, sub_array, size2, MPI_INT, 0, MPI_COMM_WORLD);
tmp_array = { new int[size2] {} };
mergeSort(sub_array, tmp_array, 0, (size2 - 1));
MPI_Gather(sub_array, size2, MPI_INT, sorted, size2, MPI_INT, 0, MPI_COMM_WORLD);
}
else {
sub_array = { new int[size] {} };
MPI_Scatter(original_array, size, MPI_INT, sub_array, size, MPI_INT, 0, MPI_COMM_WORLD);
tmp_array = { new int[size] {} };
mergeSort(sub_array, tmp_array, 0, (size - 1));
MPI_Gather(sub_array, size, MPI_INT, sorted, size, MPI_INT, 0, MPI_COMM_WORLD);
}
但给出错误“ MPI_Gather中的致命错误:消息被截断,错误堆栈:MPI_Gather(sbuf = 0x00A2A700,scount = 4,MPI_INT,rbuf = 0x00A302C8,rcount = 4,MPI_INT,root = 0,MPI_COMM_WORLD)失败来自等级1和标记的消息-1342177184被截断;收到28个字节,但对于数组中的奇数个元素,缓冲区大小为16“。
但是,当数组的大小为奇数时,过程1执行上述if
部分if and else
,而其他过程执行该else
部分。因此,某些进程将调用例程MPI_Gather
并MPI_Scatter
使用不同的count
。这些例程应该在所有进程中都以相同的方式调用。
要修复代码,您可以对其进行更改,以便所有进程都使用相同count
的MPI_Scatter
和MPI_Gather
例程进行调用。
通常,当输入的大小没有平均地除以进程数时,将面临与您相同的问题。为了解决这个问题,可以将伪值添加到数组中,以便将大小除以进程数。或者可以使用MPI_Gatherv:
从组中的所有流程聚集到指定位置
将缓冲区分散散布到通信器中的所有进程
从源头可以看到:
MPI_Gatherv和MPI_Scatterv是MPI_Gather和MPI_Scatter的可变消息大小版本。MPI_Gatherv扩展了MPI_Gather的功能,以允许来自每个进程的数据数量变化,并允许在将收集的数据放在根进程上的位置上具有一定的灵活性。它通过将count参数从单个整数更改为整数数组并提供新的参数displs(数组)来实现此目的。MPI_Scatterv以类似的方式扩展MPI_Scatter。有关使用这些例程的更多信息,将在本模块后面的应用示例中提供。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句