"undefined variable" 警告,但变量已在所有进程中定义
"undefined variable" warning, yet variable is defined in all processes
编辑:发布的最新代码,直到最后一个警告...警告说明第 97 行 "recvbuffer"(在 MPI_Send 中)未定义...但我定义了 recvbuffer [totalnums] 在这一点之前的所有进程中。为什么当我到达代码的合并排序部分时,程序没有保留我定义的 recvbuffer 数组变量?
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <mpi.h>
#define TAG 25
int compare(const void *a, const void *b) { /* Comparison function for qsort */
int var1, var2, ret;
var1 = *(const int *)a;
var2 = *(const int *)b;
if (var1 == var2) {
ret = 0;
}
else {
ret = (var1 < var2) ? -1 : 1;
}
return ret;
}
int main(int argc, char *argv[]) {
int rank, process; /* Variable declarations */
MPI_Init(&argc, &argv); /* Initialize MPI */
MPI_Comm_size(MPI_COMM_WORLD, &process);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int size, origsize, h, i, j, k, p, q, r, s, v, x, z, chunk; /* Variable declarations */
int totalnums; /* Variable declarations */
if (rank != 0) { /* Receive totalnums value from process 0 for all processes */
MPI_Recv(&totalnums, 1, MPI_INT, 0, TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
int recvbuffer[totalnums]; /* Create recvbuffer array for all processes except root */
qsort(recvbuffer, chunk, sizeof(int), compare);
}
if (rank == 0) {
FILE *infilename; /* Initialize input file variable */
infilename = fopen(argv[1], "r"); /* Read input file */
if (infilename == 0) { /* Check whether read-in file exists */
printf("File not found.\n");
return 1;
}
fscanf(infilename, "%d", &size); /* Obtain total number of items in file */
totalnums = size;
while (totalnums % process != 0) { /* Obtain total number of spots to allocate in array */
totalnums += 1;
}
int A[totalnums]; /* Declare array size */
for (i = 0; i<size; i++) { /* Create array A[] from file using process 0 until end of file reached*/
fscanf(infilename, "%d", &A[i]);
}
origsize = size; /* Store original value for total numbers in file */
for (x = size; x < totalnums; x++) { /* Fill in empty spots at end of array with INT_MAX numbers */
A[x] = INT_MAX;
}
fclose(infilename); /* Close the incoming file */
MPI_Bcast(&origsize, 1, MPI_INT, 0, MPI_COMM_WORLD); /* Broadcast origsize and send totalnums to all processes */
for (h = 1; h < process; h++) {
MPI_Send(&totalnums, 1, MPI_INT, h, TAG, MPI_COMM_WORLD);
}
int recvbuffer[totalnums]; /* Create recvbuffer array in process 0 */
chunk = totalnums/process; /* Calculate chunk size for each process */
MPI_Scatter(A, chunk, MPI_INT, recvbuffer, chunk, MPI_INT, 0, MPI_COMM_WORLD); /* Send select chunk to each process */
qsort(recvbuffer, chunk, sizeof(int), compare); /* Perform sort on each chunk in individual processes */
}
int step, mergebuffer[totalnums], combinedbuffer[totalnums]; /* Create step and mergebuffer array variables */
printf("stage 2 complete.\n");
for (z = 0; z <= ((process-1)/2); z++) { /* Start mergesort */
for (step = 1; step < process; step = 2*step) {
if (rank % (2*(2 << z)*step) != 0) {
MPI_Send(recvbuffer, (2 << z)*chunk, MPI_INT, rank-(step*(2 << z)), TAG, MPI_COMM_WORLD); /* Send elements to partner process */
break;
}
else {
MPI_Recv(mergebuffer, (2 << z)*chunk, MPI_INT, rank+(step*(2 << z)), TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); /* Receive elements from partner process and store in mergebuffer */
p = 0;
q = 0;
r = 0;
while (p != (2 << z)*chunk && q != (2 << z)*chunk) { /* Start combining and sorting buffers */
if (recvbuffer[p] > mergebuffer[q] || q == (2 << z)*chunk) {
combinedbuffer[r] = recvbuffer[p];
r++;
p++;
}
else if (recvbuffer[p] <= mergebuffer[q] || p == (2 << z)*chunk) {
combinedbuffer[r] = mergebuffer[q];
r++;
q++;
}
}
v = 0;
while (v != (2 << z)*chunk) { /* Copy combinedbuffer into recvbuffer to start next iteration */
recvbuffer[v] = combinedbuffer[v];
}
}
}
printf("get to here?\n");
}
if (rank == 0) {
FILE *outfilename; /* Initialize output file variable */
outfilename = fopen(argv[2], "w"); /* Create output file */
fprintf(outfilename, "Sorted array of %d elements:\n", origsize); /* Print first line of output file */
s = 0;
for (j = 0; j < (totalnums/10); j++) { /* Create multiple rows of 10 numbers per row */
for (k = 0; k < 10; k++) { /* Cycle 10 times */
if (recvbuffer[s] != INT_MAX) { /* Print next number to file until first INT_MAX entry reached */
fprintf(outfilename, "%d ", recvbuffer[s]);
}
s++; /* Increase value to proceed through entire list */
}
fprintf(outfilename, "\n\n"); /* Print two returns at end of each 10 number row */
}
fclose(outfilename); /* Close the outgoing file */
printf("Stage 4 complete.\n");
}
MPI_Finalize(); /* Finalize MPI */
printf("\n");
return 0;
}
在回答您关于 MPI_Bcast
存在问题的评论时。您正在调用该函数 3 次。
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
第一个参数采用缓冲区的地址。你的三个电话中的最后一个是这个
MPI_Bcast(recvbuffer, totalnums, MPI_INT, 0, MPI_COMM_WORLD);
这看起来不错,因为您传递了缓冲区(并隐式地传递了它的地址)及其大小。但是你的前两个电话是
MPI_Bcast(origsize, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(totalnums, 1, MPI_INT, 0, MPI_COMM_WORLD);
在这两种情况下,您都传递了一个包含 1 个元素的缓冲区,但没有传递缓冲区 地址。虽然我没有完全遵循你的代码,但我建议你试试这个:
MPI_Bcast(&origsize, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&totalnums, 1, MPI_INT, 0, MPI_COMM_WORLD);
注意添加的 &
表示地址。在第一条语句中,您传递了一个数组,因此它的地址隐含在语句中,而不是单个整数。
编辑:发布的最新代码,直到最后一个警告...警告说明第 97 行 "recvbuffer"(在 MPI_Send 中)未定义...但我定义了 recvbuffer [totalnums] 在这一点之前的所有进程中。为什么当我到达代码的合并排序部分时,程序没有保留我定义的 recvbuffer 数组变量?
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <mpi.h>
#define TAG 25
int compare(const void *a, const void *b) { /* Comparison function for qsort */
int var1, var2, ret;
var1 = *(const int *)a;
var2 = *(const int *)b;
if (var1 == var2) {
ret = 0;
}
else {
ret = (var1 < var2) ? -1 : 1;
}
return ret;
}
int main(int argc, char *argv[]) {
int rank, process; /* Variable declarations */
MPI_Init(&argc, &argv); /* Initialize MPI */
MPI_Comm_size(MPI_COMM_WORLD, &process);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int size, origsize, h, i, j, k, p, q, r, s, v, x, z, chunk; /* Variable declarations */
int totalnums; /* Variable declarations */
if (rank != 0) { /* Receive totalnums value from process 0 for all processes */
MPI_Recv(&totalnums, 1, MPI_INT, 0, TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
int recvbuffer[totalnums]; /* Create recvbuffer array for all processes except root */
qsort(recvbuffer, chunk, sizeof(int), compare);
}
if (rank == 0) {
FILE *infilename; /* Initialize input file variable */
infilename = fopen(argv[1], "r"); /* Read input file */
if (infilename == 0) { /* Check whether read-in file exists */
printf("File not found.\n");
return 1;
}
fscanf(infilename, "%d", &size); /* Obtain total number of items in file */
totalnums = size;
while (totalnums % process != 0) { /* Obtain total number of spots to allocate in array */
totalnums += 1;
}
int A[totalnums]; /* Declare array size */
for (i = 0; i<size; i++) { /* Create array A[] from file using process 0 until end of file reached*/
fscanf(infilename, "%d", &A[i]);
}
origsize = size; /* Store original value for total numbers in file */
for (x = size; x < totalnums; x++) { /* Fill in empty spots at end of array with INT_MAX numbers */
A[x] = INT_MAX;
}
fclose(infilename); /* Close the incoming file */
MPI_Bcast(&origsize, 1, MPI_INT, 0, MPI_COMM_WORLD); /* Broadcast origsize and send totalnums to all processes */
for (h = 1; h < process; h++) {
MPI_Send(&totalnums, 1, MPI_INT, h, TAG, MPI_COMM_WORLD);
}
int recvbuffer[totalnums]; /* Create recvbuffer array in process 0 */
chunk = totalnums/process; /* Calculate chunk size for each process */
MPI_Scatter(A, chunk, MPI_INT, recvbuffer, chunk, MPI_INT, 0, MPI_COMM_WORLD); /* Send select chunk to each process */
qsort(recvbuffer, chunk, sizeof(int), compare); /* Perform sort on each chunk in individual processes */
}
int step, mergebuffer[totalnums], combinedbuffer[totalnums]; /* Create step and mergebuffer array variables */
printf("stage 2 complete.\n");
for (z = 0; z <= ((process-1)/2); z++) { /* Start mergesort */
for (step = 1; step < process; step = 2*step) {
if (rank % (2*(2 << z)*step) != 0) {
MPI_Send(recvbuffer, (2 << z)*chunk, MPI_INT, rank-(step*(2 << z)), TAG, MPI_COMM_WORLD); /* Send elements to partner process */
break;
}
else {
MPI_Recv(mergebuffer, (2 << z)*chunk, MPI_INT, rank+(step*(2 << z)), TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); /* Receive elements from partner process and store in mergebuffer */
p = 0;
q = 0;
r = 0;
while (p != (2 << z)*chunk && q != (2 << z)*chunk) { /* Start combining and sorting buffers */
if (recvbuffer[p] > mergebuffer[q] || q == (2 << z)*chunk) {
combinedbuffer[r] = recvbuffer[p];
r++;
p++;
}
else if (recvbuffer[p] <= mergebuffer[q] || p == (2 << z)*chunk) {
combinedbuffer[r] = mergebuffer[q];
r++;
q++;
}
}
v = 0;
while (v != (2 << z)*chunk) { /* Copy combinedbuffer into recvbuffer to start next iteration */
recvbuffer[v] = combinedbuffer[v];
}
}
}
printf("get to here?\n");
}
if (rank == 0) {
FILE *outfilename; /* Initialize output file variable */
outfilename = fopen(argv[2], "w"); /* Create output file */
fprintf(outfilename, "Sorted array of %d elements:\n", origsize); /* Print first line of output file */
s = 0;
for (j = 0; j < (totalnums/10); j++) { /* Create multiple rows of 10 numbers per row */
for (k = 0; k < 10; k++) { /* Cycle 10 times */
if (recvbuffer[s] != INT_MAX) { /* Print next number to file until first INT_MAX entry reached */
fprintf(outfilename, "%d ", recvbuffer[s]);
}
s++; /* Increase value to proceed through entire list */
}
fprintf(outfilename, "\n\n"); /* Print two returns at end of each 10 number row */
}
fclose(outfilename); /* Close the outgoing file */
printf("Stage 4 complete.\n");
}
MPI_Finalize(); /* Finalize MPI */
printf("\n");
return 0;
}
在回答您关于 MPI_Bcast
存在问题的评论时。您正在调用该函数 3 次。
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
第一个参数采用缓冲区的地址。你的三个电话中的最后一个是这个
MPI_Bcast(recvbuffer, totalnums, MPI_INT, 0, MPI_COMM_WORLD);
这看起来不错,因为您传递了缓冲区(并隐式地传递了它的地址)及其大小。但是你的前两个电话是
MPI_Bcast(origsize, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(totalnums, 1, MPI_INT, 0, MPI_COMM_WORLD);
在这两种情况下,您都传递了一个包含 1 个元素的缓冲区,但没有传递缓冲区 地址。虽然我没有完全遵循你的代码,但我建议你试试这个:
MPI_Bcast(&origsize, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&totalnums, 1, MPI_INT, 0, MPI_COMM_WORLD);
注意添加的 &
表示地址。在第一条语句中,您传递了一个数组,因此它的地址隐含在语句中,而不是单个整数。