Status Init()

in tensorflow_io/core/kernels/hdf5_kernels.cc [125:312]


  Status Init(const string& input) {
    mutex_lock l(mu_);

    filename_ = input;

    file_image_.reset(new HDF5FileImage(env_, filename_, ""));
    H5::H5File* file = file_image_->GetFile();
    if (file == nullptr) {
      return errors::InvalidArgument("unable to open hdf5 file: ", filename_);
    }

    H5O_info_t info;
    file->getObjinfo(info);
    HDF5Iterate data(info.addr);
    herr_t err = H5Literate(file->getId(), H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
                            HDF5Iterate::Iterate, (void*)&data);

    for (size_t i = 0; i < data.datasets_.size(); i++) {
      ::tensorflow::DataType dtype;
      string dataset = data.datasets_[i];
      H5::DataSet data_set = file->openDataSet(dataset);

      H5::DataSpace data_space = data_set.getSpace();
      int rank = data_space.getSimpleExtentNdims();
      absl::InlinedVector<hsize_t, 4> dims(rank);
      data_space.getSimpleExtentDims(dims.data());

      H5::DataType data_type = data_set.getDataType();
      switch (data_type.getClass()) {
        case H5T_INTEGER:
          switch (data_type.getSize()) {
            case 1:
              dtype = static_cast<H5::IntType&>(data_type).getSign() ? DT_INT8
                                                                     : DT_UINT8;
              break;
            case 2:
              dtype = static_cast<H5::IntType&>(data_type).getSign()
                          ? DT_INT16
                          : DT_UINT16;
              break;
            case 4:
              dtype = static_cast<H5::IntType&>(data_type).getSign()
                          ? DT_INT32
                          : DT_UINT32;
              break;
            case 8:
              dtype = static_cast<H5::IntType&>(data_type).getSign()
                          ? DT_INT64
                          : DT_UINT64;
              break;
            default:
              return errors::InvalidArgument("unsupported data type size for ",
                                             dataset, ": ",
                                             data_type.getSize());
          }
          break;
        case H5T_FLOAT:
          switch (data_type.getSize()) {
            case 4:
              dtype = DT_FLOAT;
              break;
            case 8:
              dtype = DT_DOUBLE;
              break;
            default:
              return errors::InvalidArgument("unsupported data type size for ",
                                             dataset, ": ",
                                             data_type.getSize());
          }
          break;
        case H5T_STRING:
          dtype = DT_STRING;
          break;
        case H5T_VLEN:
          dtype = DT_STRING;
          break;
        case H5T_COMPOUND:
          if (static_cast<H5::CompType&>(data_type).getNmembers() != 2) {
            return errors::InvalidArgument(
                "unsupported compound members for ", dataset, ": ",
                static_cast<H5::CompType&>(data_type).getNmembers());
          }
          if (static_cast<H5::CompType&>(data_type).getMemberName(0) !=
                  complex_names_.first ||
              static_cast<H5::CompType&>(data_type).getMemberName(1) !=
                  complex_names_.second) {
            return errors::InvalidArgument(
                "unsupported compound member names for ", dataset, ": ",
                static_cast<H5::CompType&>(data_type).getMemberName(0), ", ",
                static_cast<H5::CompType&>(data_type).getMemberName(1));
          }
          if (static_cast<H5::CompType&>(data_type).getMemberDataType(0) !=
              static_cast<H5::CompType&>(data_type).getMemberDataType(1)) {
            return errors::InvalidArgument(
                "unsupported compound with different data type for ", dataset,
                ": ", static_cast<H5::CompType&>(data_type).getMemberClass(0),
                ", ", static_cast<H5::CompType&>(data_type).getMemberClass(1));
          }
          if (static_cast<H5::CompType&>(data_type).getMemberClass(0) !=
              H5T_FLOAT) {
            return errors::InvalidArgument(
                "unsupported compound with non-float data class for ", dataset,
                ": ", static_cast<H5::CompType&>(data_type).getMemberClass(0));
          }
          switch (static_cast<H5::CompType&>(data_type)
                      .getMemberDataType(0)
                      .getSize()) {
            case 4:
              dtype = DT_COMPLEX64;
              break;
            case 8:
              dtype = DT_COMPLEX128;
              break;
            default:
              return errors::InvalidArgument(
                  "unsupported data type size for compound", dataset, ": ",
                  static_cast<H5::CompType&>(data_type)
                      .getMemberDataType(0)
                      .getSize());
          }
          break;
        case H5T_ENUM: {
          bool success = false;
          if (data_type.getSize() == 1 &&
              data_type.getSize() == DataTypeSize(DT_BOOL) &&
              static_cast<H5::EnumType&>(data_type).getNmembers() == 2) {
            int index_false = 0, index_true = 0;
            try {
              index_false =
                  static_cast<H5::EnumType&>(data_type).getMemberIndex("FALSE");
              index_true =
                  static_cast<H5::EnumType&>(data_type).getMemberIndex("TRUE");
            } catch (H5::DataTypeIException e) {
            }
            char value_false = 0, value_true = 0;
            try {
              static_cast<H5::EnumType&>(data_type).getMemberValue(
                  0, &value_false);
              static_cast<H5::EnumType&>(data_type).getMemberValue(1,
                                                                   &value_true);
            } catch (H5::DataTypeIException e) {
            }
            if (index_false == 0 && index_true == 1 && value_false == 0 &&
                value_true == 1) {
              success = true;
            }
          }
          if (!success) {
            string names = "[";
            for (int ii = 0;
                 ii < static_cast<H5::EnumType&>(data_type).getNmembers();
                 ii++) {
              int value;
              static_cast<H5::EnumType&>(data_type).getMemberValue(ii, &value);
              string name =
                  static_cast<H5::EnumType&>(data_type).nameOf(&value, 100);
              if (ii != 0) {
                names += ", ";
              }
              names += name;
            }
            names += "]";
            return errors::InvalidArgument("unsupported data class for enum: ",
                                           names);
          }
        }
          dtype = DT_BOOL;
          break;
        default:
          return errors::InvalidArgument("unsupported data class for ", dataset,
                                         ": ", data_type.getClass());
      }

      dtypes_.emplace_back(dtype);
      absl::InlinedVector<int64, 4> shape_dims(rank);
      for (int r = 0; r < rank; r++) {
        shape_dims[r] = dims[r];
      }
      shapes_.emplace_back(TensorShape(shape_dims));
    }

    columns_index_.reserve(data.datasets_.size());
    for (size_t i = 0; i < data.datasets_.size(); i++) {
      columns_index_[data.datasets_[i]] = i;
    }

    return Status::OK();
  }