# Path: caput/mpiutil.py
# def enable_mpi_exception_handler():
#     def mpi_excepthook(exc_type, exc_obj, exc_tb):
#     def __repr__(self):
# def active_comm(aprocs):
# def active(aprocs):
# def close(aprocs):
# def partition_list(full_list, i, n, method="con"):
#     def _partition(N, n, i):
# def partition_list_mpi(full_list, method="con", comm=_comm):
# def mpirange(*args, **kargs):
# def barrier(comm=_comm):
# def bcast(data, root=0, comm=_comm):
# def allreduce(sendobj, op=None, comm=_comm):
# def parallel_map(func, glist, root=None, method="con", comm=_comm):
# def typemap(dtype):
# def split_m(n, m):
# def split_all(n, comm=_comm):
# def split_local(n, comm=_comm):
# def gather_local(global_array, local_array, local_start, root=0, comm=_comm):
# def transpose_blocks(row_array, shape, comm=_comm):
# def allocate_hdf5_dataset(fname, dsetname, shape, dtype, comm=_comm):
# def lock_and_write_buffer(obj, fname, offset, size):
# def parallel_rows_write_hdf5(fname, dsetname, local_data, shape, comm=_comm):
#     def __init__(
#         self,
#         add_mpi_info: bool = True,
#         level_rank0: int = logging.INFO,
#         level_all: int = logging.WARN,
#         comm: Optional["MPI.Intracomm"] = None,
#     ):
#     def filter(self, record):
#     def __init__(self, self_module, baked_args=None):
#     def __getattr__(self, name):
#     def __call__(self, **kwargs):
# class _close_message:
# class MPILogFilter(logging.Filter):  # pylint: disable=too-few-public-methods
# class SelfWrapper(ModuleType):
#     N = len(full_list)
# 
# Path: caput/misc.py
# def vectorize(**base_kwargs):
#         def __init__(self, func):
#         def __call__(self, *args, **kwargs):
#         def __get__(self, obj, objtype=None):
# def scalarize(dtype=np.float64):
#         def __init__(self, func):
#         def __call__(self, *args, **kwargs):
#         def _make_array(x):
#         def __get__(self, obj, objtype=None):
# def listize(**_):
#         def __init__(self, func):
#         def __call__(self, *args, **kwargs):
#         def __get__(self, obj, objtype=None):
# def open_h5py_mpi(f, mode, use_mpi=True, comm=None):
#     def __init__(self, name, preserve=False, comm=None):
#     def __enter__(self):
#     def __exit__(self, exc_type, exc_val, exc_tb):
#     def tmpfile(self):
#     def lockfile(self):
# def getfullargspec(*args, **kwargs):
# def import_class(class_path):
#     class _vectorize_desc:
#     class _scalarize_desc:
#     class _listize_desc:
# class lock_file:


import os
import time
import logging
import numpy as np
                import warnings
        import h5py
        import h5py
            import warnings
from caput import mpiutil, misc
        from mpi4py import MPI
    @classmethod
    def from_hdf5(cls, f, dataset, comm=None, axis=0, sel=None):
        """Read MPIArray from an HDF5 dataset in parallel.

        Parameters
        ----------
        f : filename, or `h5py.File` object
            File to read dataset from.
        dataset : string
            Name of dataset to read from. Must exist.
        comm : MPI.Comm, optional
            MPI communicator to distribute over. If `None` optional, use
            `MPI.COMM_WORLD`.
        axis : int, optional
            Axis over which the read should be distributed. This can be used
            to select the most efficient axis for the reading.
        sel : tuple, optional
            A tuple of slice objects used to make a selection from the array
            *before* reading. The output will be this selection from the dataset
            distributed over the given axis.

        Returns
        -------
        array : MPIArray
        """
        # Don't bother using MPI where the axis is not zero. It's probably just slower.
        # TODO: with tuning this might not be true. Keep an eye on this.
        use_mpi = axis > 0

        # Read the file. Opening with MPI if requested, and we can

# Path: caput/mpiutil.py
# def enable_mpi_exception_handler():
#     def mpi_excepthook(exc_type, exc_obj, exc_tb):
#     def __repr__(self):
# def active_comm(aprocs):
# def active(aprocs):
# def close(aprocs):
# def partition_list(full_list, i, n, method="con"):
#     def _partition(N, n, i):
# def partition_list_mpi(full_list, method="con", comm=_comm):
# def mpirange(*args, **kargs):
# def barrier(comm=_comm):
# def bcast(data, root=0, comm=_comm):
# def allreduce(sendobj, op=None, comm=_comm):
# def parallel_map(func, glist, root=None, method="con", comm=_comm):
# def typemap(dtype):
# def split_m(n, m):
# def split_all(n, comm=_comm):
# def split_local(n, comm=_comm):
# def gather_local(global_array, local_array, local_start, root=0, comm=_comm):
# def transpose_blocks(row_array, shape, comm=_comm):
# def allocate_hdf5_dataset(fname, dsetname, shape, dtype, comm=_comm):
# def lock_and_write_buffer(obj, fname, offset, size):
# def parallel_rows_write_hdf5(fname, dsetname, local_data, shape, comm=_comm):
#     def __init__(
#         self,
#         add_mpi_info: bool = True,
#         level_rank0: int = logging.INFO,
#         level_all: int = logging.WARN,
#         comm: Optional["MPI.Intracomm"] = None,
#     ):
#     def filter(self, record):
#     def __init__(self, self_module, baked_args=None):
#     def __getattr__(self, name):
#     def __call__(self, **kwargs):
# class _close_message:
# class MPILogFilter(logging.Filter):  # pylint: disable=too-few-public-methods
# class SelfWrapper(ModuleType):
#     N = len(full_list)
# 
# Path: caput/misc.py
# def vectorize(**base_kwargs):
#         def __init__(self, func):
#         def __call__(self, *args, **kwargs):
#         def __get__(self, obj, objtype=None):
# def scalarize(dtype=np.float64):
#         def __init__(self, func):
#         def __call__(self, *args, **kwargs):
#         def _make_array(x):
#         def __get__(self, obj, objtype=None):
# def listize(**_):
#         def __init__(self, func):
#         def __call__(self, *args, **kwargs):
#         def __get__(self, obj, objtype=None):
# def open_h5py_mpi(f, mode, use_mpi=True, comm=None):
#     def __init__(self, name, preserve=False, comm=None):
#     def __enter__(self):
#     def __exit__(self, exc_type, exc_val, exc_tb):
#     def tmpfile(self):
#     def lockfile(self):
# def getfullargspec(*args, **kwargs):
# def import_class(class_path):
#     class _vectorize_desc:
#     class _scalarize_desc:
#     class _listize_desc:
# class lock_file:


# Path: caput/mpiarray.py
import os
import time
import logging
import numpy as np
                import warnings
        import h5py
        import h5py
            import warnings
from caput import mpiutil, misc
        from mpi4py import MPI

    @classmethod
    def from_hdf5(cls, f, dataset, comm=None, axis=0, sel=None):
        """Read MPIArray from an HDF5 dataset in parallel.

        Parameters
        ----------
        f : filename, or `h5py.File` object
            File to read dataset from.
        dataset : string
            Name of dataset to read from. Must exist.
        comm : MPI.Comm, optional
            MPI communicator to distribute over. If `None` optional, use
            `MPI.COMM_WORLD`.
        axis : int, optional
            Axis over which the read should be distributed. This can be used
            to select the most efficient axis for the reading.
        sel : tuple, optional
            A tuple of slice objects used to make a selection from the array
            *before* reading. The output will be this selection from the dataset
            distributed over the given axis.

        Returns
        -------
        array : MPIArray
        """
        # Don't bother using MPI where the axis is not zero. It's probably just slower.
        # TODO: with tuning this might not be true. Keep an eye on this.
        use_mpi = axis > 0

        # Read the file. Opening with MPI if requested, and we can

        fh = misc.open_h5py_mpi(f, "r", use_mpi=use_mpi, comm=comm)