是否可以知道以HDF5格式存储的矩阵是在RowMajor还是ColMajor?例如,当我从octave中保存矩阵时,它将它们内部存储为ColMajor,当我在C代码中读取它们时,我需要转置它们,其中矩阵存储在RowMajor中,反之亦然。
答案 0 :(得分:5)
HDF5按行主要顺序存储数据:
HDF5使用C存储约定,假设最后列出的维度是变化最快的维度,并且首先列出的维度是最慢的维度。
然而,如果您使用Octave的内置HDF5界面,它会自动为您调换阵列。一般来说,如何在HDF5文件中实际写入数据应该对最终用户完全不透明,并且接口应该处理数组排序等方面的差异。
答案 1 :(得分:4)
正如@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
}
}
}
}
}
注意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);
}
编译并运行时给出:
~$ h5cc -o rmat rmat.c
~$ ./rmat
rank: 2 dimensions: (3 x 2)
A/value:
[ 1 4 ]
[ 2 5 ]
[ 3 6 ]
这很好,因为它意味着矩阵在内存中优化存储。它的意思是,你必须改变你的计算方式。对于行主要,您需要进行预乘,而对于列主要,您应该进行后乘。 这是一个example,希望它解释得更清楚。
这有帮助吗?