“未定义变量”警告,但变量已在所有进程中定义

Posted

技术标签:

【中文标题】“未定义变量”警告,但变量已在所有进程中定义【英文标题】:"undefined variable" warning, yet variable is defined in all processes 【发布时间】:2015-02-23 16:59:25 【问题描述】:

编辑:发布的最新代码,直到最后一个警告...警告说明在第 97 行“recvbuffer”(在 MPI_Send 中)未定义...但我在之前的所有进程中定义了 recvbuffer[totalnums]这点。为什么当我到达代码的mergesort部分时程序没有保留我定义的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;


【问题讨论】:

了解如何使用调试器;投资将获得丰厚回报。 即使没有调试器,您也可以通过插入printf() 提示找到导致故障的行。分而治之:从中间开始,淘汰一半或另一半,等等。 哪个等级的段错误? 感谢 printf() 语句的想法。我找到了我的第一个麻烦区域。我的 MPI_Bcast 语句有问题,但不确定是什么错误... 这段代码甚至没有接近编译。编译时发布的代码中有许多警告和几个错误,请启用所有警告。 (在 gcc 中,使用类似 -Wall -Wextra -W -pedantic)在代码中,始终检查返回值(例如来自 fscanf、fopen、MPI 函数以确保操作成功。S当它实际/干净编译时,然后使用调试器,例如 GDB(编译并使用 '-ggdb' 参数链接以获得最佳结果) 【参考方案1】:

在回答您的评论时,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);

注意添加的&amp; 以指示地址。在第一个语句中,您传递了一个数组,因此它的地址隐含在语句中,而不是单个整数。

【讨论】:

非常感谢!我已将“&”添加到所有字符串中,并且在这一点上似乎可以正常工作(使用 printf 进行检查)。但是您使用原始“recvbuffer”的方式也有效。非常感谢!我还在第 114 行和第 119 行收到有关“正在查找 (int),已收到 (int *)”的错误 - 在我打印到 outfile 的代码末尾。有任何想法吗?我是否删除第 115 行中的“&”?尝试打印“\n\n”(双重返回)怎么样?有没有其他方法可以做到这一点,或者我是否会从其他地方得到错误? fprintf(outfilename, "Sorted array of %d elements:\n", &amp;origsize); 或打印recvbuffer[s] 时不应使用&amp;。虽然你为什么使用int origsizeint totalnums 来表示MPI_Bcast() 等,但我无法理解。 非常感谢您的帮助,我确实删除了recvbuffer前面的&,但没有看到您提到的另一个。由于某种原因,警告行号与代码中的位置不一致。现在看起来好多了,只需要整理 3 到 4 个警告。不错,我不认为我构建的第一个 C 程序 :) 再次感谢您的帮助!

以上是关于“未定义变量”警告,但变量已在所有进程中定义的主要内容,如果未能解决你的问题,请参考以下文章

mysqli_query 上的未定义变量

如何修复自定义模块中的“未定义变量”

Laravel 6未定义变量:工作

未定义变量:文件(查看:\resources\views\home.blade.php)

错误:使用 Sass 的 Angular 组件中的未定义变量

PHP 和未定义变量策略