2014-06-09 15 views
5

Có thể biết liệu ma trận được lưu trữ ở định dạng HDF5 có trong RowMajor hoặc ColMajor không? Ví dụ khi tôi lưu ma trận từ quãng tám, lưu trữ chúng trong nội bộ như ColMajor, tôi cần phải chuyển đổi chúng khi tôi đọc chúng trong mã C của tôi, nơi ma trận được lưu trữ trong RowMajor, và ngược lại.HDF5 rowmajor hoặc colmajor

Trả lời

4

HDF5 lưu trữ dữ liệu trong hàng trật tự chính:

HDF5 sử dụng công ước lưu trữ C, giả định rằng kích thước niêm yết cuối cùng là nhanh nhất thay đổi kích thước và kích thước đầu tiên niêm yết được sự thay đổi chậm nhất.

từ HDF5 User's Guide.

Tuy nhiên, nếu bạn đang sử dụng giao diện HDF5 tích hợp của Octave, nó sẽ tự động chuyển mảng cho bạn. Nói chung, cách dữ liệu thực sự được ghi trong tệp HDF5 phải hoàn toàn mờ đục đối với người dùng cuối và giao diện phải đối phó với sự khác biệt trong thứ tự mảng, v.v.

+0

Vì vậy, khi tôi đọc dữ liệu được xuất từ ​​octave và chúng được chuyển đổi là do thực tế là Octave không tuân theo quy ước HDF5, phải không? – remi

+0

Bạn đang sử dụng cái gì để đọc nó? – Yossarian

+0

Tôi đang sử dụng một mã trong C++ được viết bởi chính tôi. Tôi chỉ đọc thứ nguyên số liệu rồi đọc các giá trị. – remi

4

Như @Yossarian đã chỉ ra. HDF5 luôn lưu trữ dữ liệu dưới dạng hàng lớn (quy ước C). Octave giống với Fortran và lưu trữ dữ liệu dưới dạng cột chính.

Khi viết ma trận từ Octave, lớp HDF5 sẽ chuyển vị trí cho bạn, vì vậy nó luôn được viết thành hàng chính bất kể bạn sử dụng ngôn ngữ nào. Điều này cung cấp tính di động của tệp.

Có một ví dụ rất hay trong phần Hướng dẫn sử dụng HDF5 7.3.2.5, như đã đề cập bởi @Yossarian. Dưới đây là ví dụ (gần như) tái sử dụng 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 <[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 
     } 
     } 
    } 
} 
} 

Thông báo như thế nào lớp HDF5 đã hoán ma trận để chắc chắn rằng nó được lưu trữ trong định dạng hàng-lớn.

Sau đó, một ví dụ về đọc nó trong 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); 
} 

Khi biên soạn và chạy cho:

~$ h5cc -o rmat rmat.c 
~$ ./rmat 
rank: 2 dimensions: (3 x 2) 
A/value: 
[ 1 4 ] 
[ 2 5 ] 
[ 3 6 ] 

này là rất tốt vì nó có nghĩa là các ma trận được lưu trữ tối ưu hóa trong bộ nhớ. Điều đó có nghĩa là bạn phải thay đổi cách tính toán. Đối với hàng-lớn, bạn cần phải làm trước khi nhân, trong khi cho cột lớn bạn nên làm sau nhân. Đây là một số example, hy vọng nó được giải thích rõ ràng hơn một chút.

Điều này có hữu ích không?

+0

Thx cho ví dụ rất chi tiết.Nhưng dựa trên ví dụ của bạn, HDF5 không lưu trữ ma trận trong RowMajor: ma trận 'A', trong bộ nhớ Octave, trong ColMajor, sẽ xuất hiện dưới dạng vector 1D chứa các giá trị' {1,4,2,5,3,6 } '. Ngoài ra, mờ [0] = 2 và dim1 [1] = 3. Khi bạn đọc A trong C prog, ma trận đọc có kích thước hỗn hợp, và RowMajor, 1D bộ nhớ tương đương với ma trận đọc A cũng là {1,4,2,5,3,6}. Tôi mong đợi '{1,2,3,4,5,6}'. Ít nhất, tôi sẽ mong đợi một số gợi ý trong tập tin HDF5 để biết nếu bố trí bộ nhớ cho ma trận coeff khi viết là hàng hoặc col lớn để đọc nó tốt. – remi

Các vấn đề liên quan