# 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
        ----------
        array : np.ndarray
            Array to wrap.
        axis : integer
            Axis over which the array is distributed. The lengths are checked
            to try and ensure this is correct.
        comm : MPI.Comm, optional
            The communicator over which the array is distributed. If `None`
            (default), use `MPI.COMM_WORLD`.

        Returns
        -------
        dist_array : MPIArray
            An MPIArray view of the input.
        """

        # from mpi4py import MPI

        if comm is None:
            comm = mpiutil.world

        # Get axis length, both locally, and globally
        axlen = array.shape[axis]
        totallen = mpiutil.allreduce(axlen, comm=comm)

        # Figure out what the distributed layout should be
        local_num, local_start, _ = mpiutil.split_local(totallen, comm=comm)

        # Check the local layout is consistent with what we expect, and send
        # result to all ranks.

# 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

        ----------
        array : np.ndarray
            Array to wrap.
        axis : integer
            Axis over which the array is distributed. The lengths are checked
            to try and ensure this is correct.
        comm : MPI.Comm, optional
            The communicator over which the array is distributed. If `None`
            (default), use `MPI.COMM_WORLD`.

        Returns
        -------
        dist_array : MPIArray
            An MPIArray view of the input.
        """

        # from mpi4py import MPI

        if comm is None:
            comm = mpiutil.world

        # Get axis length, both locally, and globally
        axlen = array.shape[axis]
        totallen = mpiutil.allreduce(axlen, comm=comm)

        # Figure out what the distributed layout should be
        local_num, local_start, _ = mpiutil.split_local(totallen, comm=comm)

        # Check the local layout is consistent with what we expect, and send
        # result to all ranks.

        layout_issue = mpiutil.allreduce(axlen != local_num, op=mpiutil.MAX, comm=comm)