C MPI文件逐行读取

C MPI文件逐行读取,c,mpi,mpi-io,C,Mpi,Mpi Io,我是MPI的新学员。我想使用MPI_File_read_at()逐行读取txt文件中的数据。每行的长度是不同的,所以当我读取一行(设置缓冲区的长度)时,有时它也会读取下一行,将下一行的某些部分发送到缓冲区,这确实会造成问题。。。所以,我想知道是否有任何方法可以使用MPI_File_read_at()逐行读取数据?在每行末尾遇到“\n”时让其停止?或者您是否有更好的建议,使用MPI_File_read_at()以外的MPI函数逐行读取数据 我想我的问题是如何使用MPI_File_read_at()

我是MPI的新学员。我想使用MPI_File_read_at()逐行读取txt文件中的数据。每行的长度是不同的,所以当我读取一行(设置缓冲区的长度)时,有时它也会读取下一行,将下一行的某些部分发送到缓冲区,这确实会造成问题。。。所以,我想知道是否有任何方法可以使用MPI_File_read_at()逐行读取数据?在每行末尾遇到“\n”时让其停止?或者您是否有更好的建议,使用MPI_File_read_at()以外的MPI函数逐行读取数据

我想我的问题是如何使用MPI_File_read_at()做与fgets相同的事情

/*the traditional way to read a file line by line:*/
for(i=0;i<nlens;i++)
{
    fgets(line, 20, fp);
    sscanf(line,"%d%d",&e1,&e2);
}


/*the way I am doing this by MPI*/

int offset = 0;
int count = 15;
char line[15];
for(i=0;i<nlens;i++)
{
    offset=i*count;
    MPI_File_read_at(fp, offset, line, count, MPI_CHAR, &status);
    printf("line%d:/n%s/n",i,line);
}

/*So, if I have a file looks like:*/
0        2
0        44353
3        423
4        012312
5        2212
5        476

/*the output of mpi version  will be:*/
line0: 
0        2
0
line1:
      44353
3
line2:
      423
4
line3:
    012312
5
line4:
      2212
5
line5:
     476
2
5

void read_data(char address_data[], int num_edges, int link[][100])
{
    int i,e1,e2;
    FILE *fp;
    char line[30];

    int totalTaskNum, rankID;
    MPI_Comm_rank(MPI_COMM_WORLD, &rankID);
    MPI_Comm_size(MPI_COMM_WORLD, &totalTaskNum);
    MPI_Status status;
    if(rankID == 0)  /*to avoid different processors access to the file simultaneously*/
    {
        fp = fopen(address_data, "r");
        for(i=0;i<num_edges;i++)
        {
            fgets(line, 20, fp);
            sscanf(line,"%d%d",&e1,&e2);
            link[e1][e2]++;
        }
        fclose(fp);
    }
}
/*逐行读取文件的传统方式:*/

对于(i=0;iMPI i/O用于读取二进制文件,其中每个记录都由一个结构表示,因此通过这种方式,您可以循环记录,或在给定位置查找记录

但对于文本文件,您无法提前知道每行的结束/开始位置

如果要读取文本文件,则需要将文件的数据传递到缓冲区,然后逐字符读取数据,无论何时
c='\n'
,您都可以看到当前行结束

如果你只需要找到一行,就这样,你只需要像我说的那样读取文件,每当一行开始时增加一个计数器,这样你就知道你想要哪一行了

但是,如果您的程序需要多次查找它(可能性更大),一个想法是,您只需读取一次文件,建立一个行位置索引,然后就可以知道每行的位置。 当然,如果之后更新了文件,则需要相应地更新索引

编辑:你也可以看看这个。它过去对我很有帮助

编辑2:按您的要求。主进程将文件读入2D int数组

我创建了一个文件
matrix.txt
,并将这个
空格隔开
值:

0 2
0 44353
3 423
4 012312
5 2212
5 476
节目如下:

#include <mpi.h>

#define FILENAME    "matrix.txt"
#define WIDTH       2
#define HEIGHT      6


int main() {

    int rank, world_size;

    MPI_Init(NULL, NULL);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);


    int matrix[HEIGHT][WIDTH];

    /**
     * The MASTER process reads the file
     */
    if (rank == 0) { 
        FILE *fp = fopen(FILENAME, "r");

        char line[100];
        int i = 0;
        while (fgets(line, 100, fp)) {
            sscanf(line, "%d %d", &matrix[i][0], &matrix[i][1]);
            i++;
        }
    }

    //Broadcast it to all processes
    MPI_Bcast(matrix, HEIGHT * WIDTH, MPI_INT, 0, MPI_COMM_WORLD);

    //just for demo purposes each process prints its array orderly
    int p = 0, i = 0, j = 0;
    for (p = 0; p < world_size; p++) {
        MPI_Barrier(MPI_COMM_WORLD);
        if (p == rank) {
            printf("----------\n proc:%d received:\n", rank);
            for (i = 0; i < HEIGHT; i++) {
                for (j = 0; j < WIDTH; j++) {
                    printf("%d\t", matrix[i][j]);
                }
                printf("\n");
            }
        }
    }


    MPI_Finalize();
    return 0;
}

为什么阅读下一行的一部分会导致问题?您可以在阅读后对该行进行标记。感谢您回答我的问题。还有其他简单的方法可以读取文本文件吗?我不需要使用多个处理器来读取文件,只想像fgets()那样执行。问题是fgets()是使用mpicc编译时会导致分段错误…那么我可以像fgets()那样做吗?不需要使用mpi_File_read_at()之类的mpi函数@Ziwei你现在把我弄糊涂了。你想不想并行读取文件?如果你不想使用多个处理器/进程,为什么要使用mpi。如果你想串行读取文件(使用一个进程)然后让根进程读取它,然后对从文件中获得的数据执行任何您想要的操作。另外,您可以发布您的程序,以便我可以看到您的尝试执行什么操作吗?很抱歉,我已经发布了上面的代码(整个代码太长…因此我只显示了读取文件的函数“void read_data()”)基本上,我要做的是串行读取文件以生成矩阵,然后我将使用mpi并行化矩阵乘法。我不知道为什么使用mpicc编译后fgets()会导致分段错误
$ mpirun -np 4 ./program 
----------
 proc:0 received:
0       2       
0       44353   
3       423     
4       12312   
5       2212    
5       476     
----------
 proc:1 received:
0       2       
0       44353   
3       423     
4       12312   
5       2212    
5       476     
----------
 proc:2 received:
0       2       
0       44353   
3       423     
4       12312   
5       2212    
5       476     
----------
 proc:3 received:
0       2       
0       44353   
3       423     
4       12312   
5       2212    
5       476