2

線形配列を c++ から hdf5 ファイルの 3 次元データセットに保存する際に小さな問題があります。

メモリ内のレイアウトは次のようになります。

    |---+---+---+---+---+---+---+---+---+---+----+----|
    | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    |---+---+---+---+---+---+---+---+---+---+----+----|

プログラムによって次のように解釈されますが、

         x
    |---+---+---| 
    | 0 | 1 | 2 |
z=0 |---+---+---| y
    | 3 | 4 | 5 |     
    |---+---+---|

           x
    |---+----+----|
    | 6 |  7 |  8 |
z=1 |---+----+----|  y
    | 9 | 10 | 11 |
    |---+----+----|

次のコードを使用して、この配列を HDF5 ファイルの 3 次元データセットに保存します。

std::vector<int> buffer;
for(int i = 0; i < 12; ++i)
   buffer.push_back(i);
hsize_t dims[3] = {2,3,2};
    hisze_t mem_dim[1] = {12};
hid_t file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    hid_t space = H5Screate_simple (3, dims, NULL);
hid_t mem_space = H5Screate_simple(1,mem_dim,NULL);

hid_t dset = H5Dcreate (file, DATASET, H5T_STD_I32LE, space, H5P_DEFAULT,
                       H5P_DEFAULT, H5P_DEFAULT);
herr_t status = H5Dwrite (dset, H5T_NATIVE_INT, mem_space, space, H5P_DEFAULT,
                   &buffer[0]);

次のようなレイアウトになります。

         x
   |---+---+----|      
   | 0 | 2 |  4 |
z=0|---+---+----| y
   | 6 | 8 | 10 |
   |---+---+----|

         x
   |---+----+----|
   | 1 |  3 |  5 |
z=1|---+----+----|  y
   | 7 | 9  | 11 |
   |---+----+----|

これは、行優先の形式 (z は最も変化の速いインデックス) のためだと思います。とにかく、H5DWriteを1回呼び出すだけで、hdf5に期待されるフォーマットを強制的に書き込むことは可能ですか?

私はこのアイデアを思いつきましたが、うまくいきません。ハイパースラップの機能が間違っていると思います。

    ... //Same as above, but before H5DWrite
    hsize_t start[3];
    hsize_t stride[3];
    hsize_t count[3];
    hsize_t block[3];

    //Select two blocks from array. First for z=0, second for z=1
    start[0] = 0;
    stride[0] = 6;
    count[0] = 2;
    block[0] = 6;
    status = H5Sselect_hyperslab (mem_space, H5S_SELECT_SET, start, stride, count,
             block);

    start[0] = 0;
    start[1] = 0;
    start[2] = 0;

    stride[0] = 2;
    stride[1] = 3;
    stride[2] = 1;

    count[0] = 1;
    count[1] = 1;
    count[2] = 2;

    block[0] = 2;
    block[1] = 3;
    block[2] = 1;

    status = H5Sselect_hyperslab (space, H5S_SELECT_SET, start, stride, count,
             block);

    status = H5Dwrite (dset, H5T_NATIVE_INT, mem_space, space, H5P_DEFAULT,
                      &buffer[0]);

H5Sselect_hyperslab の私の解釈では、mem_space 用に定義された 2 つのブロックは、ファイル スペースの 2 つのブロックにマップされます。しかし、実際の結果は上記と同じです。配列を再フォーマットせずに、ループで H5DWrite を呼び出さずに、期待される動作を実現することは可能ですか?

4

1 に答える 1

2

ハイパースラブはセルをスキップすることしかできず、並べ替えることはできません。だからあなたは運が悪いと思います。

あなたが言ったように、2つの解決策があります:

  1. ファイル内の配列を並べ替えます。新しいディメンションは次のようになります。

    hsize_t dims[3] = {2,2,3};
                       ^ ^ ^
                       z i j
    

    その後、1 回の書き込みで配列をダンプできます。

  2. ループ内のスラブごとに配列スラブを記述します。

メモリ内で配列を並べ替えるのは時間の無駄です。

于 2013-11-18T21:18:41.813 に答える