Source code for lascar.container.hdf5_container

# This file is part of lascar
#
# lascar is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
#
# Copyright 2018 Manuel San Pedro, Victor Servant, Charles Guillemet, Ledger SAS - manuel.sanpedro@ledger.fr, victor.servant@ledger.fr, charles@ledger.fr

"""
hdf5_container.py
"""
import h5py

from lascar.container import TraceBatchContainer, Container


[docs]class Hdf5Container(Container): """ Hdf5Container is a Container based upon hdf5 files (with h5py). A hdf5 file emulates a file system and can contains two types of objects: - Group = folder - Dataset = multidimensional array of data (which are loaded into np.array thanks to h5py) A Hdf5Container consists in a hdf5 file which containes at least two datasets; - 1 dataset containing the leakages - 1 dataset containing the values """ def __init__( self, filename, leakages_dataset_name="leakages", values_dataset_name="values", mode="r", **kwargs ): """ Basic constructor :param filename: :param leakages_dataset_name: :param values_dataset_name: :param mode: mode for opening filename: default is read-only """ self._file = h5py.File(filename, mode) self.leakages = self._file[leakages_dataset_name] self.values = self._file[values_dataset_name] Container.__init__(self, **kwargs) self.logger.debug( "Creating Hdf5Container from file %s with datasests %s/%s." % (filename, leakages_dataset_name, values_dataset_name) ) def __getitem__(self, key): return TraceBatchContainer.__getitem__(self, key) def __setitem__(self, key, value): TraceBatchContainer.__setitem__(self, key, value)
[docs] @staticmethod def void_container( filename, number_of_traces, leakage_shape, leakage_dtype, value_shape, value_dtype, leakages_dataset_name="leakages", values_dataset_name="values", **kwargs ): """ void_container is a static method for building an empty Hdf5Container with the specified parameters. :param filename: container filename :param number_of_traces: :param leakage_shape: shape of 1 leakage :param leakage_dtype: dtype of leakage :param value_shape: shape of 1 value :param value_dtype: dtype of value :param leakages_dataset_name: :param values_dataset_name: :return: an empty Hdf5Container """ try: # if file exists file = h5py.File(filename,"a") if leakages_dataset_name in file: del file[leakages_dataset_name] if values_dataset_name in file: del file[values_dataset_name] except: file.close() file = h5py.File(filename, "w") file.create_dataset( leakages_dataset_name, (number_of_traces,) + leakage_shape, leakage_dtype ) file.create_dataset( values_dataset_name, (number_of_traces,) + value_shape, value_dtype ) file.close() return Hdf5Container( filename, leakages_dataset_name, values_dataset_name, mode="r+", **kwargs )
[docs] @staticmethod def export( container, filename, name=None, leakages_dataset_name="leakages", values_dataset_name="values", batch_size=100, ): """ export method is used to export an existing container into an Hdf5Container. It creates a session and use a ContainerDumpEngine to recopy the traces delivered by the original container. :param container: container to be exported :param filename: name of the Hdf5Container to build :param leakages_dataset_name: :param values_dataset_name: :param batch_size: :return: """ leakage, value = container[0] out = Hdf5Container.void_container( filename, container.number_of_traces, leakage.shape, leakage.dtype, value.shape, value.dtype, leakages_dataset_name, values_dataset_name, ) from lascar import Session from lascar.engine import ContainerDumpEngine session = Session( container, engine=ContainerDumpEngine(out), name=name if name else "Hdf5Container", ) session.run(batch_size) # Adding mean/var: to leakage_dataset_name as attributes try: out._file[leakages_dataset_name].attrs["mean"] = session["mean"].finalize() out._file[leakages_dataset_name].attrs["var"] = session["var"].finalize() except: pass return out
[docs] def get_leakage_mean_var(self): """ Compute mean/var of the leakage. :return: mean/var of the container leakages """ try: mean, var = self.leakages.attrs["mean"], self.leakages.attrs["var"] return self.apply_both_leakage(mean), self.apply_both_leakage(var) except: mean, var = Container.get_leakage_mean_var(self) try: self.leakages.attrs["mean"] = mean self.leakages.attrs["var"] = var except: pass return mean, var