c - 在 C 中使用 mpi 在函数中分配和填充二维数组

标签 c arrays mpi

我正在尝试读取一个 ascii 文件,该文件由 2 列和可变的 nr 行组成。读取由处理器 0 完成,然后使用 MPI_Bcast(...) 分发数据。我必须创建一个 1-dim 缓冲区数组,其中包含数据并发送到所有其他 proc,因为我还没有找到直接广播 2-dim 的方法。数据。 数组arr的分配有问题。当我尝试打印数据时,打印了前 3 行,然后出现段错误。很可能有几个错误。

我真的试图让这个例子尽可能简单。 我的代码:

//global variables 
...
double **testarray;
int      dim; 
...
int main(int argc, char **argv){
   ...
   ...
    read_file("test.txt",&testarray,&dim);  
}

int read_file(char* infilename,double ***arr,int *rowsout)
{

  FILE* infile;
  int i,j,ch,number_of_lines=0;
  int rows=0;    
  //first count lines
  if(myid==0)      //myid is processor id
  {
    infile = fopen(infilename, "r");
    do
    {
       ch = fgetc(infile);
       if(ch == '\n')
         number_of_lines++;
    } while (ch != EOF);
    if(ch != '\n' && number_of_lines != 0)
      number_of_lines++;
    //close file
    fclose(infile);
    rows=number_of_lines-1;
    *rowsout=rows;
  }
  // every proc should know about length of file in order
  //to be able to allocate memory
  MPI_Bcast(rowsout,1,MPI_INT,0,MPI_COMM_WORLD);

  //allocate memory
  double *buf;     //1D-buffer for 2D-array
  MPI_Alloc_mem((*rowsout)*2*sizeof(double), MPI_INFO_NULL, &buf);
  MPI_Alloc_mem((*rowsout)*sizeof(double*), MPI_INFO_NULL,arr);
  for (i = 0; i < (*rowsout); i++) {
    MPI_Alloc_mem(2*sizeof(double),MPI_INFO_NULL,&arr[i]);
  }
  // Now read file on proc 0
  if(myid==0)
  {
    infile=fopen(infilename,"r");
    for(i=0;i<rows;i++)
    {
      for(j=0;j<2;j++)
      {
        fscanf(infile,"%lf",arr[i][j]);
        printf("arr[%d][%d]:%e\n",i,j,(*arr)[i][j]);
      }
    }
    fclose(infile);
  }
  return 0;

  //dont go further, error occurs before loop finishs
  MPI_Bcast(buf,(rows)*2,MPI_DOUBLE,0,MPI_COMM_WORLD);

  //now reconstruct array from buffer  
  for(i=0;i<(*rowsout);i++)
  {
    for(j=0;j<2;j++)
    {
      *arr[i][j]=buf[i*2+j];
    }
  }
  MPI_Free_mem(buf);
  return 0;
}

最佳答案

如您所料,您的 arr 有一些问题。这是您的代码的固定版本(减去 MPI 内容):

#include <stdio.h>
#include <stdlib.h>

void read_file(char *filename, double ***arr, int *rowsout);

int main(void)
{
    double **testarray;
    int dim;

    read_file("test.txt", &testarray, &dim);

    return 0;
}

void read_file(char *filename, double ***arr, int *rowsout)
{
    FILE *infile;
    int i, j, ch;

    infile = fopen(filename, "r");

    do
    {
            ch = fgetc(infile);
            if (ch == '\n')
                    ++*rowsout;
    } while (ch != EOF);
    rewind(infile);

    *arr = malloc(sizeof **arr * *rowsout);

    for (i = 0; i < *rowsout; ++i)
            (*arr)[i] = malloc(sizeof ***arr * 2);

    for (i = 0; i < *rowsout; ++i)
    {
            for (j = 0; j < 2; ++j)
            {
                    fscanf(infile, "%lf", &(*arr)[i][j]);
                    printf("(*arr)[%d][%d]: %e\n", i, j, (*arr)[i][j]);
            }
    }

    fclose(infile);
    for (i = 0; i < *rowsout; ++i)
            free((*arr)[i]);
    free(*arr);
}

示例输入:test.txt

0.01 0.02
0.3 0.4
5.0 6.0

示例输出:

(*arr)[0][0]: 1.000000e-02
(*arr)[0][1]: 2.000000e-02
(*arr)[1][0]: 3.000000e-01
(*arr)[1][1]: 4.000000e-01
(*arr)[2][0]: 5.000000e+00
(*arr)[2][1]: 6.000000e+00

我认为错误来自于您的 fscanf() 行。当您使用 "%lf" 时,fscanf() 想要一个 double *,但您传递的是 arr[i][ j] 这有两个问题:因为 arr 实际上是一个指向二维数组的指针,所以你需要先对它进行引用 ((*arr)),其次,因为它需要 double 的地址,所以你需要使用 &: &(*arr)[i​​][ j].

关于c - 在 C 中使用 mpi 在函数中分配和填充二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38902889/

相关文章:

c - 为什么 fgets 不能从 popen 流中获取所有字节

javascript - 重构 C 函数以在 O(n) 到 JavaScript 中查找二叉树的直径

arrays - 如何在 Swift 中打乱数组?

python - 通过更改键对 Python 字典进行排序,现在当我尝试迭代它时,它会迭代更改后的键

c - 在 C 中使用 MPI 发送 2D 数组行 block

mapreduce - MPI标准与Mapreduce编程模型的比较?

const char** 和 free()

c - 段错误,无法递增

javascript - 如何使用日期数组javascript创建计数对象数组

c++ - MPI_Irecv 没有收到循环后发送的消息