Writing a Dynamic Multidimensional Array to HDF

Hello,

Hopefully somebody has an idea...

I'm using C++ and I dynamically created a multidimensional array. I
manipulate it and then try to write to an HDF. I get this error and have
been unable to figure out why.

Initializing HDF Results File...HDF5-DIAG: Error detected in HDF5 library
version: 1.6.7 thread 0. Back trace follows.

  #000: ..\..\src\H5Dio.c line 697 in H5Dwrite(): can't write data

    major(15): Dataset interface

    minor(25): Write failed

  #001: ..\..\src\H5Dio.c line 1063 in H5D_write(): can't write data

    major(15): Dataset interface

    minor(25): Write failed

  #002: ..\..\src\H5Dio.c line 1438 in H5D_contig_write(): optimized write
failed

    major(15): Dataset interface

    minor(25): Write failed

  #003: ..\..\src\H5Dselect.c line 655 in H5D_select_write(): write error

    major(14): Dataspace interface

    minor(25): Write failed

  #004: ..\..\src\H5Dcontig.c line 854 in H5D_contig_writevv(): block write
failed

    major(05): Low-level I/O layer

    minor(25): Write failed

  #005: ..\..\src\H5F.c line 3338 in H5F_block_write(): file write failed

    major(05): Low-level I/O layer

    minor(25): Write failed

  #006: ..\..\src\H5FD.c line 3492 in H5FD_write(): driver write request
failed

    major(22): Virtual File Layer

    minor(25): Write failed

  #007: ..\..\src\H5FDsec2.c line 805 in H5FD_sec2_write(): file write failed

    major(05): Low-level I/O layer

    minor(25): Write failed

  #008: ..\..\src\H5FDsec2.c line 805 in H5FD_sec2_write(): Invalid argument

    major(03): Internal HDF5 error

    minor(87): System error message

I have a hunch it's because the HDF is trying to write the pointers to the
file, instead of the 2D array.

Here is my SIMPLIFIED code... There are no errors and everything it correct,
until I try to write

template <typename T>

T **AllocateDynamicArray(int nRows, int nCols)

{

      T **dynamicArray;

      dynamicArray = new T*[nRows];

      for( int i = 0 ; i < nRows ; i++ )

      dynamicArray[i] = new T [nCols];

      return dynamicArray;

}

void initResultsHDF(int **Results)

{

            //Then I fill the array with all 0's and try to print it but this
is the line that gives the error.

dataset.write(Results, PredType::NATIVE_INT, memspace, dataspace);

}

int main()

{

int **Results = AllocateDynamicArray<int>(SIZEROW,SIZECOL); //Correctly
creates a dynamic multidimensional array

            initResultsHDF(Results); //Sends the dynamically created
multidimensional array to the function

}

Very respectfully,

Phil Salesses
Cartographic Technician
U.S. Army Topographic Engineering Center (TEC)
7701 Telegraph Road
Alexandria, VA 22315-3864
Mark.P.Salesses@usace.army.mil

TEC R&D - Anything But Ordinary

Hi Phil,

Hello,

Hopefully somebody has an idea…
I’m using C++ and I dynamically created a multidimensional array. I manipulate it and then try to write to an HDF. I get this error and have been unable to figure out why.

Initializing HDF Results File...HDF5-DIAG: Error detected in HDF5 library version: 1.6.7 thread 0. Back trace follows.
  #000: ..\..\src\H5Dio.c line 697 in H5Dwrite(): can't write data
    major(15): Dataset interface
    minor(25): Write failed
  #001: ..\..\src\H5Dio.c line 1063 in H5D_write(): can't write data
    major(15): Dataset interface
    minor(25): Write failed
  #002: ..\..\src\H5Dio.c line 1438 in H5D_contig_write(): optimized write failed
    major(15): Dataset interface
    minor(25): Write failed
  #003: ..\..\src\H5Dselect.c line 655 in H5D_select_write(): write error
    major(14): Dataspace interface
    minor(25): Write failed
  #004: ..\..\src\H5Dcontig.c line 854 in H5D_contig_writevv(): block write failed
    major(05): Low-level I/O layer
    minor(25): Write failed
  #005: ..\..\src\H5F.c line 3338 in H5F_block_write(): file write failed
    major(05): Low-level I/O layer
    minor(25): Write failed
  #006: ..\..\src\H5FD.c line 3492 in H5FD_write(): driver write request failed
    major(22): Virtual File Layer
    minor(25): Write failed
  #007: ..\..\src\H5FDsec2.c line 805 in H5FD_sec2_write(): file write failed
    major(05): Low-level I/O layer
    minor(25): Write failed
  #008: ..\..\src\H5FDsec2.c line 805 in H5FD_sec2_write(): Invalid argument
    major(03): Internal HDF5 error
    minor(87): System error message

I have a hunch it’s because the HDF is trying to write the pointers to the file, instead of the 2D array.

  Yes, that's probably your problem. The HDF5 library expects to receive a contiguous array of elements, not pointers to elements in lower dimensions.

  Quincey

···

On Jun 11, 2008, at 10:44 AM, Salesses, Mark P ERDC-TEC-VA wrote:

Here is my SIMPLIFIED code… There are no errors and everything it correct, until I try to write

template <typename T>
T **AllocateDynamicArray(int nRows, int nCols)
{
      T **dynamicArray;

      dynamicArray = new T*[nRows];
      for( int i = 0 ; i < nRows ; i++ )
      dynamicArray[i] = new T [nCols];

      return dynamicArray;
}

void initResultsHDF(int **Results)
{
            //Then I fill the array with all 0’s and try to print it but this is the line that gives the error.
dataset.write(Results, PredType::NATIVE_INT, memspace, dataspace);
}

int main()
{
int **Results = AllocateDynamicArray<int>(SIZEROW,SIZECOL); //Correctly creates a dynamic multidimensional array
            initResultsHDF(Results); //Sends the dynamically created multidimensional array to the function
}
Very respectfully,
Phil Salesses
Cartographic Technician
U.S. Army Topographic Engineering Center (TEC)
7701 Telegraph Road
Alexandria, VA 22315-3864
Mark.P.Salesses@usace.army.mil

TEC R&D - Anything But Ordinary

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

hello Mark

Hi Phil,

Hello,

Hopefully somebody has an idea…
I’m using C++ and I dynamically created a multidimensional array. I
manipulate it and then try to write to an HDF. I get this error and
have been unable to figure out why.

Initializing HDF Results File...HDF5-DIAG: Error detected in HDF5
library version: 1.6.7 thread 0. Back trace follows.
#000: ..\..\src\H5Dio.c line 697 in H5Dwrite(): can't write data
   major(15): Dataset interface
   minor(25): Write failed
#001: ..\..\src\H5Dio.c line 1063 in H5D_write(): can't write data
   major(15): Dataset interface
   minor(25): Write failed
#002: ..\..\src\H5Dio.c line 1438 in H5D_contig_write(): optimized
write failed
   major(15): Dataset interface
   minor(25): Write failed
#003: ..\..\src\H5Dselect.c line 655 in H5D_select_write(): write
error
   major(14): Dataspace interface
   minor(25): Write failed
#004: ..\..\src\H5Dcontig.c line 854 in H5D_contig_writevv():
block write failed
   major(05): Low-level I/O layer
   minor(25): Write failed
#005: ..\..\src\H5F.c line 3338 in H5F_block_write(): file write
failed
   major(05): Low-level I/O layer
   minor(25): Write failed
#006: ..\..\src\H5FD.c line 3492 in H5FD_write(): driver write
request failed
   major(22): Virtual File Layer
   minor(25): Write failed
#007: ..\..\src\H5FDsec2.c line 805 in H5FD_sec2_write(): file
write failed
   major(05): Low-level I/O layer
   minor(25): Write failed
#008: ..\..\src\H5FDsec2.c line 805 in H5FD_sec2_write(): Invalid
argument
   major(03): Internal HDF5 error
   minor(87): System error message

I have a hunch it’s because the HDF is trying to write the pointers
to the file, instead of the 2D array.

       Yes, that's probably your problem. The HDF5 library expects to
receive a contiguous array of elements, not pointers to elements in
lower dimensions.

       Quincey

Here is my SIMPLIFIED code… There are no errors and everything it
correct, until I try to write

template <typename T>
T **AllocateDynamicArray(int nRows, int nCols)
{
     T **dynamicArray;

     dynamicArray = new T*[nRows];
     for( int i = 0 ; i < nRows ; i++ )
     dynamicArray[i] = new T [nCols];

     return dynamicArray;
}

void initResultsHDF(int **Results)
{
           //Then I fill the array with all 0’s and try to print it
but this is the line that gives the error.
dataset.write(Results, PredType::NATIVE_INT, memspace, dataspace);
}

int main()
{
int **Results = AllocateDynamicArray<int>(SIZEROW,SIZECOL); // Correctly creates a dynamic multidimensional array
           initResultsHDF(Results); //Sends the dynamically created
multidimensional array to the function
}
Very respectfully,
Phil Salesses
Cartographic Technician
U.S. Army Topographic Engineering Center (TEC)
7701 Telegraph Road
Alexandria, VA 22315-3864
Mark.P.Salesses@usace.army.mil

TEC R&D - Anything But Ordinary

you can do a "trick" to do this

since

int **Results

is an array of pointers of rows where each one points to another array of columns (i.e a 2D dynamic array), it's possible to do an iteration by rows having in each one a column selected and writing each time a hyperslab ( a column)

in your function

void initResultsHDF(int **Results)

do this

for( int i = 0 ; i < SIZEROW ; i++ )
{
....

int *row_start = Results[i];

you'll get a pointer to the start of the row and then you can use this pointer to call the write routine of HDF5, that, like Quincey said, expects to receive a contiguous array of elements (or a pointer)

You'll have to write each row each time, by selecting this hyperslab in the file (one row) and also defining a memory hyperslab with this row

Below it is a complete C++ program that I adapted from your sample (I defined a matrix of 4 x 3 )
and from our C++ examples

the output of the program should be

writing row 0
1 2 3
writing row 1
4 5 6
writing row 2
7 8 9
writing row 3
10 11 12

I also send it attached

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdfgroup.org/HDF5/doc/Copyright.html\. If you do not have *
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifdef OLD_HEADER_FILENAME
#include <iostream.h>
#else
#include <iostream>
#endif
#include <string>

#ifndef H5_NO_NAMESPACE
#ifndef H5_NO_STD
    using std::cout;
    using std::endl;
#endif // H5_NO_STD
#endif

#include "H5Cpp.h"

#ifndef H5_NO_NAMESPACE
    using namespace H5;
#endif

template <typename T>
T **AllocateDynamicArray(int nRows, int nCols)
{
    
    T **dynamicArray;
    
    dynamicArray = new T*[nRows];
    
    for( int i = 0 ; i < nRows ; i++ )
        
        dynamicArray[i] = new T [nCols];
    
    return dynamicArray;
    
}

#define SIZEROW 4
#define SIZECOL 3

void initResultsHDF(int **Results)
{

        H5File* file = new H5File( "_myfile.h5", H5F_ACC_TRUNC );
        
        hsize_t dims[] = {SIZEROW, SIZECOL};
        DataSpace fspace( 2, dims );
        
        DataSet dataset(file->createDataSet("mydset", PredType::NATIVE_INT, fspace));

    // define a memory space to write each row

        hsize_t row[] = {SIZECOL};
        DataSpace mspace( 1, row );

    for( int i = 0 ; i < SIZEROW ; i++ )
    {
        
        // select file hyperslab
        
        hsize_t start[2]; // start of hyperslab
        hsize_t stride[2] = {1, 1}; // stride of hyperslab
        hsize_t count[2]; // block count
        hsize_t block[2] = {1, 1}; // block sizes
        
        count[0] = 1;
        count[1] = SIZECOL;

        start[0] = i;
        start[1] = 0;
        
        fspace.selectHyperslab( H5S_SELECT_SET, count, start, stride, block);
        
        // select memory hyperslab
        
        hsize_t mstart[1] = {0}; // start of hyperslab
        hsize_t mstride[1] = {1}; // stride of hyperslab
        hsize_t mcount[1] = {SIZECOL}; // block count
        hsize_t mblock[1] = {1}; // block sizes
        
        mspace.selectHyperslab( H5S_SELECT_SET, mcount, mstart, mstride, mblock);
        
        int *row_start = Results[i];

        printf("writing row %d\n", i );
        for( int j = 0 ; j < SIZECOL ; j++ )
            printf("%d ", Results[i][j]);
        printf("\n");
        
        dataset.write(row_start, PredType::NATIVE_INT, mspace, fspace);
        
    }
    
        delete file;
        
}

int main()
{
    
    int **Results = AllocateDynamicArray<int>(SIZEROW,SIZECOL); //Correctly creates a dynamic multidimensional array

    int n = 1;
    for( int i = 0 ; i < SIZEROW ; i++ )
    {
        for( int j = 0 ; j < SIZECOL ; j++ )
        {
         Results[i][j] = n++;
        }
    }
    
    initResultsHDF(Results); //Sends the dynamically created multidimensional array to the function

    return 0;
    
}

dynamicArray.cpp (3.75 KB)

_myfile.h5 (2.05 KB)

···

At 12:09 PM 6/11/2008, Quincey Koziol wrote:

On Jun 11, 2008, at 10:44 AM, Salesses, Mark P ERDC-TEC-VA wrote:

----------------------------------------------------------------------
This mailing list is for HDF software users discussion.
To subscribe to this list, send a message to hdf-forum-subscribe@hdfgroup.org.
To unsubscribe, send a message to hdf-forum-unsubscribe@hdfgroup.org.

--------------------------------------------------------------
Pedro Vicente (T) 217.265-0311
pvn@hdfgroup.org
The HDF Group. 1901 S. First. Champaign, IL 61820