HDF5 Slicing



  • Ich habe ein HDF5 file mit einem dataset der Dimension 100x3x480x640, dh. 100 Bilder, 3-kanalig mit Height 480 und Width 640.

    Ich möchte nun nacheinander die Bilder möglichst effizient in den Ram laden und verarbeiten. dh ich möchte immer nur auf "sub Felder" der Größe 3x480x640 zugreifen, da das ganze sonst mein RAM sprengt. Dazu bediene ichmich der C/C++ API und hyperslabs

    #include <iostream>
    #include <vector>
    #include "H5Cpp.h"
    
    const H5std_string FILE_NAME("mypath");
    const auto DATASET_NAME("Camera");
    using namespace H5;
    int main() {
    
        Exception::dontPrint();
        
         // Open the specified file and the specified dataset in the file.
        auto file = H5File(FILE_NAME, H5F_ACC_RDONLY);
        auto dataset = file.openDataSet(DATASET_NAME);
        /*
         * Get the class of the datatype that is used by the dataset.
         */
        auto type_class = dataset.getTypeClass();
        if (type_class == H5T_INTEGER) {
          std::cout << "Data set has INTEGER type" << std::endl;
          auto intype = dataset.getIntType();
          auto order_string = H5std_string();
          auto order = intype.getOrder(order_string);
          std::cout << order_string << std::endl;
          auto size = intype.getSize();
          std::cout << "Int size in Byte " << size << std::endl;
        }
       
        auto dataspace = dataset.getSpace();
        auto rank = dataspace.getSimpleExtentNdims();
        hsize_t dims_out[rank];
        dataspace.getSimpleExtentDims(dims_out);
        std::cout << "rank " << rank << ", dimensions "
                  << (unsigned long)(dims_out[0]) << " x "
                  << (unsigned long)(dims_out[1]) << " x "
                  << (unsigned long)(dims_out[2]) << " x "
                  << (unsigned long)(dims_out[3]) << std::endl;
        // allocate buffer on the heap
        auto blob = std::vector<int>(dims_out[1] * dims_out[2] * dims_out[3]);
        hsize_t dimsm[] = {dims_out[1],
                           dims_out[2],
                           dims_out[3]}; /* memory space dimensions */
    
        auto memspace = DataSpace(3, dimsm);
    
        /*
         * Define hyperslab in the dataset; implicitly giving strike and
         * block NULL.
         */
        hsize_t offset[4]; // hyperslab offset in the file
        hsize_t count[4]; // size of the hyperslab in the file
        offset[0] = 1; // extract only the second image
        offset[1] = 0;
        offset[2] = 0;
        offset[3] = 0;
    // count defines the size of the sub sample I want to get
        count[0] = 1;
        count[1] = 3;
        count[2] = 480;
        count[3] = 640;
        dataspace.selectHyperslab(H5S_SELECT_SET, count, offset);
    
        // read into RAM
        dataset.read(std::data(blob), PredType::NATIVE_INT, memspace, dataspace);
       
      return 0; // successfully terminated
    }
    
    1. Ist das so effizient? ich würde dann in einer Loop jeweils offset[0] inkrementieren, oder gibt es da bessere Lösungen?

    2. wieso brauche ich hier neben meinem eigentlichen Buffer immer noch einen DataSpace bei HDF5? in den offiziellen docs finde ich dazu nichts.

    Vielen Dank für eure Hilfe



  • jemand eine meinung?



  • @Sewing sagte in HDF5 Slicing:

    jemand eine meinung?

    Nur dass du diese Fragen wohl besser nochmal in einem Forum oder einer Mailinglist für diese HDF5-Bibliothek stellen solltest. Am besten dort, wo sich auch ein paar der Entwickler tummeln. Nur mit C++-Kenntnissen kann man diese nämlich nicht wirklich beantworten. Dazu müsste man schon genauer wissen, wie die Bibliothek arbeitet. Z.B. ob die Daten direkt ohne Umwege in blob landen, oder ob sie mehrfach über dataspace und memspace herumkopiert werden - keine Ahnung. Das können leichtgewichtige Abstraktionen fast ohne Overhead sein oder auch nicht.

    Was du noch machen könntest ist nachmessen: Ist dieser Code z.B. nur unwesentlich langsamer als das direkte und unverarbeitete Einlesen in den Speicher (fread und so), dann ist dieser Code sehr wahrscheinlich ziemlich effizient.


Anmelden zum Antworten