gpt4 book ai didi

c++ - 使用 mpi 将矩阵写入单个 txt 文件

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:14:48 25 4
gpt4 key购买 nike

我有一个巨大的矩阵,我将它分成一些子矩阵,然后对其进行一些计算。在这些计算之后,我必须将该矩阵写入单个文件以进行后期处理。是否可以将结果写入单个文本文件,我该怎么做?例如,我们有一个在 y 方向上划分的 nxny 矩阵(每个进程都有一个 nxrank 矩阵),我们想将 nx*ny 矩阵写入单个文本文件。

最佳答案

所以将大量数据写成文本并不是一个好主意。它真的非常非常慢,它会生成不必要的大文件,而且处理起来很痛苦。大量数据应该写成二进制,只有人类的摘要数据写成文本。让计算机要处理的东西对计算机来说很容易,只有你真正要坐下来阅读的东西对你来说很容易处理(例如,文本)。

无论您要写入文本还是二进制文件,都可以使用 MPI-IO 将输出协调到文件以生成一个大文件。我们有一个关于该主题的小教程(使用 MPI-IO、HDF5 和 NetCDF)here .对于 MPI-IO,诀窍是定义一个类型(这里是一个子数组)来根据文件的全局布局来描述数据的局部布局,然后使用它作为“ View ”写入文件。每个文件只能看到自己的 View ,MPI-IO 库会协调输出,因此只要 View 不重叠,所有内容都会作为一个大文件输出。

如果我们用二进制写出来,我们只需将 MPI_Write 指向我们的数据并完成它;因为我们使用的是文本,所以我们必须将数据转换成字符串。我们按照通常的方式定义我们的数组,除了它不是 MPI_FLOATs,它是一种新类型,每个数字是 charspernum 个字符。

代码如下:

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

float **alloc2d(int n, int m) {
float *data = malloc(n*m*sizeof(float));
float **array = malloc(n*sizeof(float *));
for (int i=0; i<n; i++)
array[i] = &(data[i*m]);
return array;
}

int main(int argc, char **argv) {
int ierr, rank, size;
MPI_Offset offset;
MPI_File file;
MPI_Status status;
MPI_Datatype num_as_string;
MPI_Datatype localarray;
const int nrows=10;
const int ncols=10;
float **data;
char *const fmt="%8.3f ";
char *const endfmt="%8.3f\n";
int startrow, endrow, locnrows;

const int charspernum=9;

ierr = MPI_Init(&argc, &argv);
ierr|= MPI_Comm_size(MPI_COMM_WORLD, &size);
ierr|= MPI_Comm_rank(MPI_COMM_WORLD, &rank);

locnrows = nrows/size;
startrow = rank * locnrows;
endrow = startrow + locnrows - 1;
if (rank == size-1) {
endrow = nrows - 1;
locnrows = endrow - startrow + 1;
}

/* allocate local data */
data = alloc2d(locnrows, ncols);

/* fill local data */
for (int i=0; i<locnrows; i++)
for (int j=0; j<ncols; j++)
data[i][j] = rank;

/* each number is represented by charspernum chars */
MPI_Type_contiguous(charspernum, MPI_CHAR, &num_as_string);
MPI_Type_commit(&num_as_string);

/* convert our data into txt */
char *data_as_txt = malloc(locnrows*ncols*charspernum*sizeof(char));
int count = 0;
for (int i=0; i<locnrows; i++) {
for (int j=0; j<ncols-1; j++) {
sprintf(&data_as_txt[count*charspernum], fmt, data[i][j]);
count++;
}
sprintf(&data_as_txt[count*charspernum], endfmt, data[i][ncols-1]);
count++;
}

printf("%d: %s\n", rank, data_as_txt);

/* create a type describing our piece of the array */
int globalsizes[2] = {nrows, ncols};
int localsizes [2] = {locnrows, ncols};
int starts[2] = {startrow, 0};
int order = MPI_ORDER_C;

MPI_Type_create_subarray(2, globalsizes, localsizes, starts, order, num_as_string, &localarray);
MPI_Type_commit(&localarray);

/* open the file, and set the view */
MPI_File_open(MPI_COMM_WORLD, "all-data.txt",
MPI_MODE_CREATE|MPI_MODE_WRONLY,
MPI_INFO_NULL, &file);

MPI_File_set_view(file, 0, MPI_CHAR, localarray,
"native", MPI_INFO_NULL);

MPI_File_write_all(file, data_as_txt, locnrows*ncols, num_as_string, &status);
MPI_File_close(&file);

MPI_Type_free(&localarray);
MPI_Type_free(&num_as_string);

free(data[0]);
free(data);

MPI_Finalize();
return 0;
}

运行给出:

$ mpicc -o matrixastxt matrixastxt.c  -std=c99
$ mpirun -np 4 ./matrixastxt
$ more all-data.txt
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
2.000 2.000 2.000 2.000 2.000 2.000 2.000 2.000 2.000 2.000
2.000 2.000 2.000 2.000 2.000 2.000 2.000 2.000 2.000 2.000
3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000
3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000
3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000
3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000 3.000

关于c++ - 使用 mpi 将矩阵写入单个 txt 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9777828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com