是否可以知道以HDF5格式存储的矩阵是在RowMajor还是ColMajor?例如,当我从octave中保存矩阵时,它将它们内部存储为ColMajor,当我在C代码中读取它们时,我需要转置它们,其中矩阵存储在RowMajor中,反之亦然.
HDF5按行主要顺序存储数据:
HDF5使用C存储约定,假设最后列出的维度是变化最快的维度,并且首先列出的维度是最慢的维度.
来自HDF5用户指南.
但是,如果您使用Octave的内置HDF5接口,它将自动为您调换阵列.一般来说,如何在HDF5文件中实际写入数据应该对最终用户完全不透明,并且接口应该处理数组排序等方面的差异.
正如@Yossarian 指出的。HDF5 始终将数据存储为行优先(C 约定)。Octave 与 Fortran 相同,内部以列优先存储数据。
当从 Octave 编写矩阵时,HDF5 层会为您进行转置,因此无论您使用哪种语言,它总是以行优先形式编写。这提供了文件的可移植性。
正如 @Yossarian 所提到的,HDF5 用户指南第 7.3.2.5 节中有一个非常好的示例。这是使用 Octave 复制的(几乎)示例:
octave:1> A = [ 1:3; 4:6 ]
A =
1 2 3
4 5 6
octave:2> save("-hdf5", "test.h5", "A")
octave:3> quit
~$ h5dump test.h5
HDF5 "test.h5" {
GROUP "/" {
COMMENT "# Created by Octave 3.6.4, Fri Jun 13 08:36:16 2014 MDT <user@localhost>"
GROUP "A" {
ATTRIBUTE "OCTAVE_NEW_FORMAT" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
DATA {
(0): 1
}
}
DATASET "type" {
DATATYPE H5T_STRING {
STRSIZE 7;
STRPAD H5T_STR_NULLTERM;
CSET H5T_CSET_ASCII;
CTYPE H5T_C_S1;
}
DATASPACE SCALAR
DATA {
(0): "matrix"
}
}
DATASET "value" {
DATATYPE H5T_IEEE_F64LE
DATASPACE SIMPLE { ( 3, 2 ) / ( 3, 2 ) }
DATA {
(0,0): 1, 4,
(1,0): 2, 5,
(2,0): 3, 6
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意 HDF5 层如何转置矩阵以确保其以行优先格式存储。
然后是用 C 读取它的示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hdf5.h>
#define FILE "test.h5"
#define DS "A/value"
int
main(int argc, char **argv)
{
int i = 0;
int j = 0;
int n = 0;
int x = 0;
int rank = 0;
hid_t file_id;
hid_t space_id;
hid_t dset_id;
herr_t stat;
hsize_t *dims = NULL;
int *data = NULL;
file_id = H5Fopen(FILE, H5F_ACC_RDONLY, H5P_DEFAULT);
dset_id = H5Dopen(file_id, DS, dset_id);
space_id = H5Dget_space(dset_id);
n = H5Sget_simple_extent_npoints(space_id);
rank = H5Sget_simple_extent_ndims(space_id);
dims = malloc(rank*sizeof(int));
stat = H5Sget_simple_extent_dims(space_id, dims, NULL);
printf("rank: %d\t dimensions: ", rank);
for (i = 0; i < rank; ++i) {
if (i == 0) {
printf("(");
}
printf("%llu", dims[i]);
if (i == (rank -1)) {
printf(")\n");
} else {
printf(" x ");
}
}
data = malloc(n*sizeof(int));
memset(data, 0, n*sizeof(int));
stat = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT,
data);
printf("%s:\n", DS);
for (i = 0; i < dims[0]; ++i) {
printf(" [ ");
for (j = 0; j < dims[1]; ++j) {
x = i * dims[1] + j;
printf("%d ", data[x]);
}
printf("]\n");
}
stat = H5Sclose(space_id);
stat = H5Dclose(dset_id);
stat = H5Fclose(file_id);
return(EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)
编译并运行时给出:
~$ h5cc -o rmat rmat.c
~$ ./rmat
rank: 2 dimensions: (3 x 2)
A/value:
[ 1 4 ]
[ 2 5 ]
[ 3 6 ]
Run Code Online (Sandbox Code Playgroud)
这很棒,因为这意味着矩阵在内存中进行了优化存储。但这确实意味着您必须改变计算方式。对于行优先,您需要进行预乘,而对于列优先,您应该进行后乘。这是一个例子,希望能解释得更清楚一些。
这有帮助吗?
归档时间: |
|
查看次数: |
2595 次 |
最近记录: |