C - MPI_ERR_RANK:集群排名无效



我正在为一个类做一个项目,我已经使用了互联网上顺序存储桶排序的代码,我正在尝试使用 OpenMPI 使其成为并行版本。 此代码将在群集系统上运行。当我测试它时,它给了我以下错误:

"[群集:5379] * 通信器MPI_COMM_WORLD [群集:5379] MPI_ERR_RANK上的MPI_Send [群集:5379]中发生错误: 排名无效 [集群:5379] *MPI_ERRORS_ARE_FATAL:您的 MPI 作业 现在将中止"

任何人都可以建议我如何解决它吗?

附言。我非常不擅长编码,所以我可能无法回答一些问题。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "mpi.h"
struct bucket
{
int count;
int* value;
};
int compareIntegers(const void* first, const void* second)
{
int x = *((int*)first), y = *((int*)second);
if (x == y)
{
return 0;
}
else if (x < y)
{
return -1;
}
else
{
return 1;
}
}
void bucketSort(int array[], int n)
{
struct bucket buckets[3];
int i, j, k;
for (i = 0; i < 3; i++)
{
buckets[i].count = 0;
buckets[i].value = (int*)malloc(sizeof(int) * n);
}
for (i = 0; i < n; i++)
{
if (array[i] < 0)
{
buckets[0].value[buckets[0].count++] = array[i];
}
else if (array[i] > 10)
{
buckets[2].value[buckets[2].count++] = array[i];
}
else
{
buckets[1].value[buckets[1].count++] = array[i];
}
}
for (k = 0, i = 0; i < 3; i++)
{
// now using quicksort to sort the elements of buckets
qsort(buckets[i].value, buckets[i].count, sizeof(int), &compareIntegers);
for (j = 0; j < buckets[i].count; j++)
{
array[k + j] = buckets[i].value[j];
}
k += buckets[i].count;
free(buckets[i].value);
}
}
int main(char *argv[], int argc)
{
int array[1000000];
int i = 0, j, k, n;
int num;
//for MPI
int numProc, rank;
char procName[MPI_MAX_PROCESSOR_NAME];
int nameLen;
int chunksize;
double start, end;
int msgtag;
//MPI
MPI_Status stat;
start = MPI_Wtime();    //timer start
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank); //process rank ,comm_world = communication of the process
MPI_Comm_size(MPI_COMM_WORLD, &numProc); //number of process
msgtag = 1234;
if (rank == 0)
{
printf("Enter number of element to be sort: ");
scanf("%d", &num);
for (i = 0; i < num; i++) //random num elements
{
array[i] = rand();
}
n = i;
printf("nBefore Sortingn");
for (j = 0; j < i; j++)
{
printf("%d ", array[j]);
}
MPI_Send(&array[j], j, MPI_INT, 1, msgtag, MPI_COMM_WORLD);
}
if (rank == 1)
{
MPI_Recv(&array[j], j, MPI_INT, 0, msgtag, MPI_COMM_WORLD, &stat);
bucketSort(array, n);
MPI_Send(&array, n, MPI_INT, 2, msgtag, MPI_COMM_WORLD);
}
if (rank == 2)
{
MPI_Recv(&array, n, MPI_INT, 1, msgtag, MPI_COMM_WORLD, &stat);
printf("nAfter Sortingn");
for (k = 0; k < i; k++)
{
printf("%d ", array[k]);
}
}
//MPI END
MPI_Finalize();
end = MPI_Wtime();  // timer end   
double time_spent = end - start;
printf("ntime used for this program was %f Sec.", time_spent);
return 0;
}

它们是代码中的很多错误。希望截止日期是星期一...

第一:

int main(int argc, char *argv[])

会比int main(int argc, char *argv[])更好

第二

进程 0 是指定用于读取要生成的元素数的进程。
然后它必须将其 brodacast 到所有其他进程,否则其他进程将在变量num中有一个未定义的数字,对吧?

因此

if (rank == 0)
{
printf("Enter number of element to be sort: ");
fflush(stdout);
scanf("%d", &num);
for (i = 0; i < num; i++) //random num elements
{
array[i] = rand();
}
n = num;
printf("nBefore Sorting (%i)n", n);
for (j = 0; j < n; j++)
{
printf("%d ", array[j]);
}
fflush(stdout);
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

第三:

避免重用循环中涉及的值。我明白之后

for (j = 0; j < n; j++)
{
printf("%d ", array[j]);
}

你有

j=n

但不是很清楚...

第四:

要MPI_Send或接收的第一个参数是数组中第一个元素的地址。所以通过

MPI_Send(&array[j], j, MPI_INT, 1, msgtag, MPI_COMM_WORLD);

既然j=n(见上面的评论(我想你不会得到你想要的。

你需要的是

MPI_Send(&array[0], n, MPI_INT, 1, msgtag, MPI_COMM_WORLD);

第五:

MPI_Barrier是你的朋友。输出是一项关键操作,因此在输出操作之前,您可以(可选(确保所有进程都已达到这一点。

if (rank == 2)
{
MPI_Recv(&array, n, MPI_INT, 1, msgtag, MPI_COMM_WORLD, &stat);
printf("nAfter Sortingn");
for (k = 0; k < i; k++)
{
printf("%d ", array[k]);
}
}

成为

if (rank == 2)
{
MPI_Recv(&(array[0]), n, MPI_INT, 1, msgtag, MPI_COMM_WORLD, &stat);
}
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 2)
{
printf("nAfter Sortingn");
for (k = 0; k < n; k++)
{
printf("%d ", array[k]);
}
}
MPI_Barrier(MPI_COMM_WORLD);

结论:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "mpi.h"
struct bucket
{
int count;
int* value;
};
int compareIntegers(const void* first, const void* second)
{
int x = *((int*)first), y = *((int*)second);
if (x == y)
{
return 0;
}
else if (x < y)
{
return -1;
}
else
{
return 1;
}
}
void bucketSort(int array[], int n)
{
struct bucket buckets[3];
int i, j, k;
for (i = 0; i < 3; i++)
{
buckets[i].count = 0;
buckets[i].value = (int*)malloc(sizeof(int) * n);
}
for (i = 0; i < n; i++)
{
if (array[i] < 0)
{
buckets[0].value[buckets[0].count++] = array[i];
}
else if (array[i] > 10)
{
buckets[2].value[buckets[2].count++] = array[i];
}
else
{
buckets[1].value[buckets[1].count++] = array[i];
}
}
for (k = 0, i = 0; i < 3; i++)
{
// now using quicksort to sort the elements of buckets
qsort(buckets[i].value, buckets[i].count, sizeof(int), &compareIntegers);
for (j = 0; j < buckets[i].count; j++)
{
array[k + j] = buckets[i].value[j];
}
k += buckets[i].count;
free(buckets[i].value);
}
}
int main(int argc, char *argv[])
{
int array[1000000];
int i = 0, j, k, n;
int num;
//for MPI
int numProc, rank;
char procName[MPI_MAX_PROCESSOR_NAME];
int nameLen;
int chunksize;
double start, end;
int msgtag;
//MPI
MPI_Status stat;
start = MPI_Wtime();    //timer start
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank); //process rank ,comm_world = communication of the process
MPI_Comm_size(MPI_COMM_WORLD, &numProc); //number of process
msgtag = 1234;
if (rank == 0)
{
printf("Enter number of element to be sort: ");
fflush(stdout);
scanf("%d", &num);
for (i = 0; i < num; i++) //random num elements
{
array[i] = rand();
}
n = num;
printf("nBefore Sortingn");
for (j = 0; j < n; j++)
{
printf("%d ", array[j]);
}
fflush(stdout);
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0)
{
MPI_Send(&(array[0]), n, MPI_INT, 1, msgtag, MPI_COMM_WORLD);
}
if (rank == 1)
{
MPI_Recv(&(array[0]), n, MPI_INT, 0, msgtag, MPI_COMM_WORLD, &stat);
bucketSort(array, n);
MPI_Send(&(array[0]), n, MPI_INT, 2, msgtag, MPI_COMM_WORLD);
}
if (rank == 2)
{
MPI_Recv(&(array[0]), n, MPI_INT, 1, msgtag, MPI_COMM_WORLD, &stat);
}
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 2)
{
printf("nAfter Sortingn");
for (k = 0; k < n; k++)
{
printf("%d ", array[k]);
}
}
//MPI END
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
end = MPI_Wtime();  // timer end   
double time_spent = end - start;
printf("ntime used for this program was %f Sec.", time_spent);
return 0;
}

运行

mpirun -np 3 test_mpi.exe

输出

Enter number of element to be sort: 10
Before Sorting
1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421
After Sorting
424238335 596516649 719885386 846930886 1189641421 1649760492 1681692777 1714636915 1804289383 1957747793
time used for this program was 2.271976 Sec.time used for this program was 2.281183 Sec.
time used for this program was 2.277746 Sec.

最新更新