0

We are integrating the HDF5 library in our .NET application.

As the HDF5 library is not thread safe we encapsulated it with the use of lock(). One thread of our program work on a single and exclusive .h5 file.

Some computations are done in parallel. For the parallel part we use :

  • threads
  • Parallel.foreach()

from :

  • System.Threading
  • System.Threading.Tasks.

Everything is working file execpt when we are executing some unit tests with NUnit v3.2.1 with thread, parallel.foreach, with a single instance of each on one single .h5 file, The final values (as they are read and written multiple times) inside our .h5 file are not correct (they are correct otherwise).

We are suspecting the HDF5 library to have an issue with the combination of all four (HDF5,NUnit,Threads,Parallel.foreach). We don't have a clear clue of what's happening.

Tools : Visual Studio 2015 Pro, NUNit v3.2.1 and NUnit3TestAdapter v3.5.1.

Any suggestions?

Thanks in advance.

Here is a sample of how we write some data inside our file :

    public void SetGroupAttribute(H5LocId hdf5Handle, string location, string attribute, int value)
    {
        lock (AccessLock)
        {
            // Retrieve the attribute to read
            var attributeId = GetAttribute(hdf5Handle, location, attribute);

            H5GroupId rootId = null;
            if (attributeId != null)
            {
                // Remove the old attribute
                rootId = H5G.open(hdf5Handle, location);
                H5A.Delete(rootId, attribute);
                H5G.close(rootId);
            }

            // Create and set the new attribute value
            H5DataSpaceId spaceId = H5S.create(H5S.H5SClass.SCALAR);
            var attributeType = H5T.copy(H5T.H5Type.NATIVE_INT);

            rootId = H5G.open(hdf5Handle, location);
            attributeId = H5A.create(rootId, attribute, attributeType, spaceId);
            H5G.close(rootId);

            // Set the attribute value
            int[] dims = new int[1];
            dims[0] = value;
            H5A.write<int>(attributeId, attributeType, new H5Array<int>(dims));
            H5A.close(attributeId);
        }
    }
Fabi1
  • 79
  • 1
  • 5
  • What's the point of using `Parallel` if you use locks? Besides, locking doesn't make something thread-safe by magic. Is `AcessLock` a static or instance field? Is anyone else using the handle? – Panagiotis Kanavos Nov 22 '16 at 09:36
  • I *wouldn't* use locking to protect such a resource. I'd use an ActionBlock](https://msdn.microsoft.com/en-us/library/hh194684(v=vs.110).aspx) to post messages to a block that performs modifications using a single task. – Panagiotis Kanavos Nov 22 '16 at 09:38
  • Parallel is used for our different computations (as we compute multiple data at the same time). AccessLock is an instance field (object) inside a singleton (where the .h5 IO methods are). I will check ActionBlock. Thanks! – Fabi1 Nov 22 '16 at 10:40
  • Just as a comment to the original post. Parallel is used to compute multiple inputs at the same time, but lock is used to use the HDF5 library one thread at a time. We agree that using locks doesn't make something thread-safe by magic, but this can avoid some problems. – Fabi1 Nov 22 '16 at 10:58

2 Answers2

0

So far I solved the problem keeping the same configuration (NUnit,threads and Parallel.foreach) by doing the following each time I edit an HDF5 file:

  1. Open the file
  2. Do IO operations
  3. Close the file
  4. ReOpen the file in read/write mode (H5F.OpenMode.ACC_RDWR)
  5. Close the the file

Each operation is secured by using lock inside our HDF5 helper singleton. This works as one thread is working on one .h5 file at a time.

It seems like the HDF5 library do async operations when you close an .h5 file, as at this step data is pushed inside the file.

The documentation is not clear about it.

I have taken this idea from this thread: HDF5 Example code

HDF5 documentation about H5F.Close: http://hdf5.net/api/M_HDF5DotNet_H5F_close_1_4829088c.aspx

Community
  • 1
  • 1
Fabi1
  • 79
  • 1
  • 5
0

The problem is now solved.

One of our operation forgot to close a dataset element from the HDF5 file, causing the H5F.Close to be ineffective.

Symptoms :

  • File is still used by the library
  • new data aren't flushed into the file

Solution:

  • check every single object from the HDF5 library that has to close once used that they are.
Fabi1
  • 79
  • 1
  • 5