2014-06-09 1 views
5

HDF5 형식으로 저장된 행렬이 RowMajor 또는 ColMajor에 있는지 여부를 알 수 있습니까? 예를 들어, ColMajor로 내부적으로 저장하는 옥타브에서 행렬을 저장할 때 행렬이 RowMajor에 저장되는 C 코드에서 해당 행렬을 변환해야합니다. 반대의 경우도 마찬가지입니다. 행 주요 순서HDF5 rowmajor 또는 colmajor

답변

4

HDF5 데이터를 저장한다 :

HDF5 마지막 나열된 사이즈가 빠르게 변화하는 사이즈 및 제 등재 치수 느린 변화라고하면, C 저장 규칙을 사용한다.

HDF5 User's Guide.

옥타브의 내장 HDF5 인터페이스를 사용하는 경우을 사용하면 자동으로 배열이 바뀝니다. 일반적으로 데이터가 실제로 HDF5 파일에 기록되는 방법은 최종 사용자에게 완전히 불투명해야하며 인터페이스는 배열 순서 등의 차이를 처리해야합니다.

+0

그래서 옥타브에서 내 보낸 데이터를 읽을 때 옥타브가 HDF5 규칙을 따르지 않았기 때문에이 데이터가 바뀌 었습니다. 맞습니까? – remi

+0

당신은 그것을 읽기 위해 무엇을 사용하고 있습니까? – Yossarian

+0

나는 C++에서 코드를 사용하고있다. 방금 데이터 세트 차원을 읽은 다음 값을 읽었습니다. – remi

4

@ Yossarian이 지적했듯이. HDF5는 항상 데이터를 행 메이저 (C 규칙)로 저장합니다. 옥타브는 Fortran과 동일하며 내부적으로 데이터를 컬럼 메이저로 저장합니다.

옥타브에서 행렬을 쓰면 HDF5 레이어가 트랜스 포즈를 수행하므로 사용하는 언어에 관계없이 항상 행 메이저로 기록됩니다. 이것은 파일의 이식성을 제공합니다.

@Yossarian에서 언급 한 것처럼 HDF5 사용 설명서 섹션 7.3.2.5에 아주 좋은 예가 있습니다. 다음은 예입니다 (거의) 옥타브를 사용하여 재현 다음 HDF5 층이이 행의 주요 형식으로 저장되어 있는지 확인하기 위해 전치 행렬을 어떻게

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 <[email protected]>" 
    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 
     } 
     } 
    } 
} 
} 

공지 사항. 이어서

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이 있습니다. 잘하면 조금 더 명확 해졌습니다.

이 정보가 도움이됩니까?

+0

Thx.그러나 당신의 예제를 기반으로 HDF5는 RowMajor에 행렬을 저장하지 않습니다 : ColMajor의 옥타브 메모리에있는 행렬 A는'{1,4,2,5,3,6] 값을 포함하는 1D 벡터로 나타납니다 }'. 또한 dim [0] = 2 및 dim1 [1] = 3입니다. C prog에서 A를 읽을 때 행렬 읽기에는 혼합 차원이 있고 읽기 A 행렬과 동일한 RowMajor, 1D 메모리도 {1,4,2,5,3,6}입니다. 나는'{1,2,3,4,5,6}'을 기대했다. 적어도, 나는 HDF5 파일의 몇 가지 힌트가, 행렬을 쓸 때의 행렬 coeff에 대한 메모리 레이아웃이 행 또는 열을 잘 읽었는지 알기를 기대합니다. – remi