from __future__ import annotations
import sys
from threading import Lock
from typing import overload
from typing import (
    Any,
    Union,
    Literal,
    Optional,
    NoReturn,
    Final,
)
if sys.version_info >= (3, 9):
    from collections.abc import (
        Callable,
        Hashable,
        Iterable,
        Iterator,
        Sequence,
        Mapping,
    )
    from builtins import (
        tuple as Tuple,
        list  as List,
        dict  as Dict,
    )
else:
    from typing import (
        Callable,
        Hashable,
        Iterable,
        Iterator,
        Sequence,
        Mapping,
    )
    from typing import (
        Tuple as Tuple,
        List  as List,
        Dict  as Dict,
    )

UNDEFINED: Final[int] = ...
ANY_SOURCE: Final[int] = ...
ANY_TAG: Final[int] = ...
PROC_NULL: Final[int] = ...
ROOT: Final[int] = ...
class _Bottom(int): ...
Bottom = _Bottom
BOTTOM: Final[Bottom] = ...
class _InPlace(int): ...
InPlace = _InPlace
IN_PLACE: Final[InPlace] = ...
KEYVAL_INVALID: Final[int] = ...
TAG_UB: Final[int] = ...
HOST: Final[int] = ...
IO: Final[int] = ...
WTIME_IS_GLOBAL: Final[int] = ...
UNIVERSE_SIZE: Final[int] = ...
APPNUM: Final[int] = ...
LASTUSEDCODE: Final[int] = ...
WIN_BASE: Final[int] = ...
WIN_SIZE: Final[int] = ...
WIN_DISP_UNIT: Final[int] = ...
WIN_CREATE_FLAVOR: Final[int] = ...
WIN_FLAVOR: Final[int] = ...
WIN_MODEL: Final[int] = ...
SUCCESS: Final[int] = ...
ERR_LASTCODE: Final[int] = ...
ERR_COMM: Final[int] = ...
ERR_GROUP: Final[int] = ...
ERR_TYPE: Final[int] = ...
ERR_REQUEST: Final[int] = ...
ERR_OP: Final[int] = ...
ERR_BUFFER: Final[int] = ...
ERR_COUNT: Final[int] = ...
ERR_TAG: Final[int] = ...
ERR_RANK: Final[int] = ...
ERR_ROOT: Final[int] = ...
ERR_TRUNCATE: Final[int] = ...
ERR_IN_STATUS: Final[int] = ...
ERR_PENDING: Final[int] = ...
ERR_TOPOLOGY: Final[int] = ...
ERR_DIMS: Final[int] = ...
ERR_ARG: Final[int] = ...
ERR_OTHER: Final[int] = ...
ERR_UNKNOWN: Final[int] = ...
ERR_INTERN: Final[int] = ...
ERR_INFO: Final[int] = ...
ERR_FILE: Final[int] = ...
ERR_WIN: Final[int] = ...
ERR_KEYVAL: Final[int] = ...
ERR_INFO_KEY: Final[int] = ...
ERR_INFO_VALUE: Final[int] = ...
ERR_INFO_NOKEY: Final[int] = ...
ERR_ACCESS: Final[int] = ...
ERR_AMODE: Final[int] = ...
ERR_BAD_FILE: Final[int] = ...
ERR_FILE_EXISTS: Final[int] = ...
ERR_FILE_IN_USE: Final[int] = ...
ERR_NO_SPACE: Final[int] = ...
ERR_NO_SUCH_FILE: Final[int] = ...
ERR_IO: Final[int] = ...
ERR_READ_ONLY: Final[int] = ...
ERR_CONVERSION: Final[int] = ...
ERR_DUP_DATAREP: Final[int] = ...
ERR_UNSUPPORTED_DATAREP: Final[int] = ...
ERR_UNSUPPORTED_OPERATION: Final[int] = ...
ERR_NAME: Final[int] = ...
ERR_NO_MEM: Final[int] = ...
ERR_NOT_SAME: Final[int] = ...
ERR_PORT: Final[int] = ...
ERR_QUOTA: Final[int] = ...
ERR_SERVICE: Final[int] = ...
ERR_SPAWN: Final[int] = ...
ERR_BASE: Final[int] = ...
ERR_SIZE: Final[int] = ...
ERR_DISP: Final[int] = ...
ERR_ASSERT: Final[int] = ...
ERR_LOCKTYPE: Final[int] = ...
ERR_RMA_CONFLICT: Final[int] = ...
ERR_RMA_SYNC: Final[int] = ...
ERR_RMA_RANGE: Final[int] = ...
ERR_RMA_ATTACH: Final[int] = ...
ERR_RMA_SHARED: Final[int] = ...
ERR_RMA_FLAVOR: Final[int] = ...
ORDER_C: Final[int] = ...
ORDER_FORTRAN: Final[int] = ...
ORDER_F: Final[int] = ...
TYPECLASS_INTEGER: Final[int] = ...
TYPECLASS_REAL: Final[int] = ...
TYPECLASS_COMPLEX: Final[int] = ...
DISTRIBUTE_NONE: Final[int] = ...
DISTRIBUTE_BLOCK: Final[int] = ...
DISTRIBUTE_CYCLIC: Final[int] = ...
DISTRIBUTE_DFLT_DARG: Final[int] = ...
COMBINER_NAMED: Final[int] = ...
COMBINER_DUP: Final[int] = ...
COMBINER_CONTIGUOUS: Final[int] = ...
COMBINER_VECTOR: Final[int] = ...
COMBINER_HVECTOR: Final[int] = ...
COMBINER_INDEXED: Final[int] = ...
COMBINER_HINDEXED: Final[int] = ...
COMBINER_INDEXED_BLOCK: Final[int] = ...
COMBINER_HINDEXED_BLOCK: Final[int] = ...
COMBINER_STRUCT: Final[int] = ...
COMBINER_SUBARRAY: Final[int] = ...
COMBINER_DARRAY: Final[int] = ...
COMBINER_RESIZED: Final[int] = ...
COMBINER_F90_REAL: Final[int] = ...
COMBINER_F90_COMPLEX: Final[int] = ...
COMBINER_F90_INTEGER: Final[int] = ...
IDENT: Final[int] = ...
CONGRUENT: Final[int] = ...
SIMILAR: Final[int] = ...
UNEQUAL: Final[int] = ...
CART: Final[int] = ...
GRAPH: Final[int] = ...
DIST_GRAPH: Final[int] = ...
UNWEIGHTED: Final[int] = ...
WEIGHTS_EMPTY: Final[int] = ...
COMM_TYPE_SHARED: Final[int] = ...
BSEND_OVERHEAD: Final[int] = ...
WIN_FLAVOR_CREATE: Final[int] = ...
WIN_FLAVOR_ALLOCATE: Final[int] = ...
WIN_FLAVOR_DYNAMIC: Final[int] = ...
WIN_FLAVOR_SHARED: Final[int] = ...
WIN_SEPARATE: Final[int] = ...
WIN_UNIFIED: Final[int] = ...
MODE_NOCHECK: Final[int] = ...
MODE_NOSTORE: Final[int] = ...
MODE_NOPUT: Final[int] = ...
MODE_NOPRECEDE: Final[int] = ...
MODE_NOSUCCEED: Final[int] = ...
LOCK_EXCLUSIVE: Final[int] = ...
LOCK_SHARED: Final[int] = ...
MODE_RDONLY: Final[int] = ...
MODE_WRONLY: Final[int] = ...
MODE_RDWR: Final[int] = ...
MODE_CREATE: Final[int] = ...
MODE_EXCL: Final[int] = ...
MODE_DELETE_ON_CLOSE: Final[int] = ...
MODE_UNIQUE_OPEN: Final[int] = ...
MODE_SEQUENTIAL: Final[int] = ...
MODE_APPEND: Final[int] = ...
SEEK_SET: Final[int] = ...
SEEK_CUR: Final[int] = ...
SEEK_END: Final[int] = ...
DISPLACEMENT_CURRENT: Final[int] = ...
DISP_CUR: Final[int] = ...
THREAD_SINGLE: Final[int] = ...
THREAD_FUNNELED: Final[int] = ...
THREAD_SERIALIZED: Final[int] = ...
THREAD_MULTIPLE: Final[int] = ...
VERSION: Final[int] = ...
SUBVERSION: Final[int] = ...
MAX_PROCESSOR_NAME: Final[int] = ...
MAX_ERROR_STRING: Final[int] = ...
MAX_PORT_NAME: Final[int] = ...
MAX_INFO_KEY: Final[int] = ...
MAX_INFO_VAL: Final[int] = ...
MAX_OBJECT_NAME: Final[int] = ...
MAX_DATAREP_STRING: Final[int] = ...
MAX_LIBRARY_VERSION_STRING: Final[int] = ...

class Datatype:
    def __new__(cls, datatype: Optional[Datatype] = None) -> Datatype: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __bool__(self) -> bool: ...
    def Get_size(self) -> int: ...
    def Get_extent(self) -> Tuple[int, int]: ...
    def Dup(self) -> Datatype: ...
    def Create_contiguous(self, count: int) -> Datatype: ...
    def Create_vector(self, count: int, blocklength: int, stride: int) -> Datatype: ...
    def Create_hvector(self, count: int, blocklength: int, stride: int) -> Datatype: ...
    def Create_indexed(self, blocklengths: Sequence[int], displacements: Sequence[int]) -> Datatype: ...
    def Create_hindexed(self, blocklengths: Sequence[int], displacements: Sequence[int]) -> Datatype: ...
    def Create_indexed_block(self, blocklength: int, displacements: Sequence[int]) -> Datatype: ...
    def Create_hindexed_block(self, blocklength: int, displacements: Sequence[int]) -> Datatype: ...
    @classmethod
    def Create_struct(cls, blocklengths: Sequence[int], displacements: Sequence[int], datatypes: Sequence[Datatype]) -> Datatype: ...
    def Create_subarray(self, sizes: Sequence[int], subsizes: Sequence[int], starts: Sequence[int], order: int = ORDER_C) -> Datatype: ...
    def Create_darray(self, size: int, rank: int, gsizes: Sequence[int], distribs: Sequence[int], dargs: Sequence[int], psizes: Sequence[int], order: int = ORDER_C) -> Datatype: ...
    @classmethod
    def Create_f90_integer(cls, r: int) -> Datatype: ...
    @classmethod
    def Create_f90_real(cls, p: int, r: int) -> Datatype: ...
    @classmethod
    def Create_f90_complex(cls, p: int, r: int) -> Datatype: ...
    @classmethod
    def Match_size(cls, typeclass: int, size: int) -> Datatype: ...
    def Commit(self) -> Datatype: ...
    def Free(self) -> None: ...
    def Create_resized(self, lb: int, extent: int) -> Datatype: ...
    def Get_true_extent(self) -> Tuple[int, int]: ...
    def Get_envelope(self) -> Tuple[int, int, int, int]: ...
    def Get_contents(self) -> Tuple[List[int], List[int], List[Datatype]]: ...
    def decode(self) -> Tuple[Datatype, str, Dict[str, Any]]: ...
    def Pack(self, inbuf: BufSpec, outbuf: BufSpec, position: int, comm: Comm) -> int: ...
    def Unpack(self, inbuf: BufSpec, position: int, outbuf: BufSpec, comm: Comm) -> int: ...
    def Pack_size(self, count: int, comm: Comm) -> int: ...
    def Pack_external(self, datarep: str, inbuf: BufSpec, outbuf: BufSpec, position: int) -> int: ...
    def Unpack_external(self, datarep: str, inbuf: BufSpec, position: int, outbuf: BufSpec) -> int: ...
    def Pack_external_size(self, datarep: str, count: int) -> int: ...
    def Get_attr(self, keyval: int) -> Optional[Union[int, Any]]: ...
    def Set_attr(self, keyval: int, attrval: Any) -> None: ...
    def Delete_attr(self, keyval: int) -> None: ...
    @classmethod
    def Create_keyval(cls, copy_fn: Optional[Callable[[Datatype, int, Any], Any]] = None, delete_fn: Optional[Callable[[Datatype, int, Any], None]] = None, nopython: bool = False) -> int: ...
    @classmethod
    def Free_keyval(cls, keyval: int) -> int: ...
    def Get_name(self) -> str: ...
    def Set_name(self, name: str) -> None: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> Datatype: ...
    size: int
    extent: int
    lb: int
    ub: int
    true_extent: int
    true_lb: int
    true_ub: int
    envelope: Tuple[int, int, int, int]
    contents: Tuple[List[int], List[int], List[Datatype]]
    combiner: int
    is_named: bool
    is_predefined: bool
    name: str
    Create_dup = Dup
    Resized = Create_resized

DATATYPE_NULL: Final[Datatype] = ...
UB: Final[Datatype] = ...
LB: Final[Datatype] = ...
PACKED: Final[Datatype] = ...
BYTE: Final[Datatype] = ...
AINT: Final[Datatype] = ...
OFFSET: Final[Datatype] = ...
COUNT: Final[Datatype] = ...
CHAR: Final[Datatype] = ...
WCHAR: Final[Datatype] = ...
SIGNED_CHAR: Final[Datatype] = ...
SHORT: Final[Datatype] = ...
INT: Final[Datatype] = ...
LONG: Final[Datatype] = ...
LONG_LONG: Final[Datatype] = ...
UNSIGNED_CHAR: Final[Datatype] = ...
UNSIGNED_SHORT: Final[Datatype] = ...
UNSIGNED: Final[Datatype] = ...
UNSIGNED_LONG: Final[Datatype] = ...
UNSIGNED_LONG_LONG: Final[Datatype] = ...
FLOAT: Final[Datatype] = ...
DOUBLE: Final[Datatype] = ...
LONG_DOUBLE: Final[Datatype] = ...
C_BOOL: Final[Datatype] = ...
INT8_T: Final[Datatype] = ...
INT16_T: Final[Datatype] = ...
INT32_T: Final[Datatype] = ...
INT64_T: Final[Datatype] = ...
UINT8_T: Final[Datatype] = ...
UINT16_T: Final[Datatype] = ...
UINT32_T: Final[Datatype] = ...
UINT64_T: Final[Datatype] = ...
C_COMPLEX: Final[Datatype] = ...
C_FLOAT_COMPLEX: Final[Datatype] = ...
C_DOUBLE_COMPLEX: Final[Datatype] = ...
C_LONG_DOUBLE_COMPLEX: Final[Datatype] = ...
CXX_BOOL: Final[Datatype] = ...
CXX_FLOAT_COMPLEX: Final[Datatype] = ...
CXX_DOUBLE_COMPLEX: Final[Datatype] = ...
CXX_LONG_DOUBLE_COMPLEX: Final[Datatype] = ...
SHORT_INT: Final[Datatype] = ...
INT_INT: Final[Datatype] = ...
TWOINT: Final[Datatype] = ...
LONG_INT: Final[Datatype] = ...
FLOAT_INT: Final[Datatype] = ...
DOUBLE_INT: Final[Datatype] = ...
LONG_DOUBLE_INT: Final[Datatype] = ...
CHARACTER: Final[Datatype] = ...
LOGICAL: Final[Datatype] = ...
INTEGER: Final[Datatype] = ...
REAL: Final[Datatype] = ...
DOUBLE_PRECISION: Final[Datatype] = ...
COMPLEX: Final[Datatype] = ...
DOUBLE_COMPLEX: Final[Datatype] = ...
LOGICAL1: Final[Datatype] = ...
LOGICAL2: Final[Datatype] = ...
LOGICAL4: Final[Datatype] = ...
LOGICAL8: Final[Datatype] = ...
INTEGER1: Final[Datatype] = ...
INTEGER2: Final[Datatype] = ...
INTEGER4: Final[Datatype] = ...
INTEGER8: Final[Datatype] = ...
INTEGER16: Final[Datatype] = ...
REAL2: Final[Datatype] = ...
REAL4: Final[Datatype] = ...
REAL8: Final[Datatype] = ...
REAL16: Final[Datatype] = ...
COMPLEX4: Final[Datatype] = ...
COMPLEX8: Final[Datatype] = ...
COMPLEX16: Final[Datatype] = ...
COMPLEX32: Final[Datatype] = ...
UNSIGNED_INT: Final[Datatype] = ...
SIGNED_SHORT: Final[Datatype] = ...
SIGNED_INT: Final[Datatype] = ...
SIGNED_LONG: Final[Datatype] = ...
SIGNED_LONG_LONG: Final[Datatype] = ...
BOOL: Final[Datatype] = ...
SINT8_T: Final[Datatype] = ...
SINT16_T: Final[Datatype] = ...
SINT32_T: Final[Datatype] = ...
SINT64_T: Final[Datatype] = ...
F_BOOL: Final[Datatype] = ...
F_INT: Final[Datatype] = ...
F_FLOAT: Final[Datatype] = ...
F_DOUBLE: Final[Datatype] = ...
F_COMPLEX: Final[Datatype] = ...
F_FLOAT_COMPLEX: Final[Datatype] = ...
F_DOUBLE_COMPLEX: Final[Datatype] = ...

class Status:
    def __new__(cls, status: Optional[Status] = None) -> Status: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def Get_source(self) -> int: ...
    def Set_source(self, source: int) -> None: ...
    def Get_tag(self) -> int: ...
    def Set_tag(self, tag: int) -> None: ...
    def Get_error(self) -> int: ...
    def Set_error(self, error: int) -> None: ...
    def Get_count(self, datatype: Datatype = BYTE) -> int: ...
    def Get_elements(self, datatype: Datatype) -> int: ...
    def Set_elements(self, datatype: Datatype, count: int) -> None: ...
    def Is_cancelled(self) -> bool: ...
    def Set_cancelled(self, flag: bool) -> None: ...
    def py2f(self) -> List[int]: ...
    @classmethod
    def f2py(cls, arg: List[int]) -> Status: ...
    source: int
    tag: int
    error: int
    count: int
    cancelled: bool

class Request:
    def __new__(cls, request: Optional[Request] = None) -> Request: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __bool__(self) -> bool: ...
    def Wait(self, status: Optional[Status] = None) -> Literal[True]: ...
    def Test(self, status: Optional[Status] = None) -> bool: ...
    def Free(self) -> None: ...
    def Get_status(self, status: Optional[Status] = None) -> bool: ...
    @classmethod
    def Waitany(cls, requests: Sequence[Request], status: Optional[Status] = None) -> int: ...
    @classmethod
    def Testany(cls, requests: Sequence[Request], status: Optional[Status] = None) -> Tuple[int, bool]: ...
    @classmethod
    def Waitall(cls, requests: Sequence[Request], statuses: Optional[List[Status]] = None) -> Literal[True]: ...
    @classmethod
    def Testall(cls, requests: Sequence[Request], statuses: Optional[List[Status]] = None) -> bool: ...
    @classmethod
    def Waitsome(cls, requests: Sequence[Request], statuses: Optional[List[Status]] = None) -> Optional[List[int]]: ...
    @classmethod
    def Testsome(cls, requests: Sequence[Request], statuses: Optional[List[Status]] = None) -> Optional[List[int]]: ...
    def Cancel(self) -> None: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> Request: ...
    def wait(self, status: Optional[Status] = None) -> Any: ...
    def test(self, status: Optional[Status] = None) -> Tuple[bool, Optional[Any]]: ...
    def get_status(self, status: Optional[Status] = None) -> bool: ...
    @classmethod
    def waitany(cls, requests: Sequence[Request], status: Optional[Status] = None) -> Tuple[int, Any]: ...
    @classmethod
    def testany(cls, requests: Sequence[Request], status: Optional[Status] = None) -> Tuple[int, bool, Optional[Any]]: ...
    @classmethod
    def waitall(cls, requests: Sequence[Request], statuses: Optional[List[Status]] = None) -> List[Any]: ...
    @classmethod
    def testall(cls, requests: Sequence[Request], statuses: Optional[List[Status]] = None) -> Tuple[bool, Optional[List[Any]]]: ...
    @classmethod
    def waitsome(cls, requests: Sequence[Request], statuses: Optional[List[Status]] = None) -> Tuple[Optional[List[int]], Optional[List[Any]]]: ...
    @classmethod
    def testsome(cls, requests: Sequence[Request], statuses: Optional[List[Status]] = None) -> Tuple[Optional[List[int]], Optional[List[Any]]]: ...
    def cancel(self) -> None: ...

REQUEST_NULL: Final[Request] = ...

class Prequest(Request):
    def __new__(cls, request: Optional[Request] = None) -> Prequest: ...
    def Start(self) -> None: ...
    @classmethod
    def Startall(cls, requests: List[Prequest]) -> None: ...

class Grequest(Request):
    def __new__(cls, request: Optional[Request] = None) -> Grequest: ...
    @classmethod
    def Start(cls, query_fn: Callable[..., None], free_fn: Callable[..., None], cancel_fn: Callable[..., None], args: Optional[Tuple[Any]] = None, kargs: Optional[Dict[str, Any]] = None) -> Grequest: ...
    def Complete(self) -> None: ...

class Message:
    def __new__(cls, message: Optional[Message] = None) -> Message: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __bool__(self) -> bool: ...
    @classmethod
    def Probe(cls, comm: Comm, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Message: ...
    @classmethod
    def Iprobe(cls, comm: Comm, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Optional[Message]: ...
    def Recv(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Irecv(self, buf: BufSpec) -> Request: ...
    @classmethod
    def probe(cls, comm: Comm, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Message: ...
    @classmethod
    def iprobe(cls, comm: Comm, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Optional[Message]: ...
    def recv(self, status: Optional[Status] = None) -> Any: ...
    def irecv(self) -> Request: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> Message: ...

MESSAGE_NULL: Final[Message] = ...
MESSAGE_NO_PROC: Final[Message] = ...

class Op:
    def __new__(cls, op: Optional[Op] = None) -> Op: ...
    def __call__(self, x: Any, y: Any) -> Any: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __bool__(self) -> bool: ...
    @classmethod
    def Create(cls, function: Callable[[Buffer, Buffer, Datatype], None], commute: bool = False) -> Op: ...
    def Free(self) -> None: ...
    def Is_commutative(self) -> bool: ...
    def Reduce_local(self, inbuf: BufSpec, inoutbuf: BufSpec) -> None: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> Op: ...
    is_commutative: bool
    is_predefined: bool

OP_NULL: Final[Op] = ...
MAX: Final[Op] = ...
MIN: Final[Op] = ...
SUM: Final[Op] = ...
PROD: Final[Op] = ...
LAND: Final[Op] = ...
BAND: Final[Op] = ...
LOR: Final[Op] = ...
BOR: Final[Op] = ...
LXOR: Final[Op] = ...
BXOR: Final[Op] = ...
MAXLOC: Final[Op] = ...
MINLOC: Final[Op] = ...
REPLACE: Final[Op] = ...
NO_OP: Final[Op] = ...

class Group:
    def __new__(cls, group: Optional[Group] = None) -> Group: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __bool__(self) -> bool: ...
    def Get_size(self) -> int: ...
    def Get_rank(self) -> int: ...
    @classmethod
    def Translate_ranks(cls, group1: Group, ranks1: Sequence[int], group2: Optional[Group] = None) -> List[int]: ...
    @classmethod
    def Compare(cls, group1: Group, group2: Group) -> int: ...
    def Dup(self) -> Group: ...
    @classmethod
    def Union(cls, group1: Group, group2: Group) -> Group: ...
    @classmethod
    def Intersection(cls, group1: Group, group2: Group) -> Group: ...
    @classmethod
    def Difference(cls, group1: Group, group2: Group) -> Group: ...
    def Incl(self, ranks: Sequence[int]) -> Group: ...
    def Excl(self, ranks: Sequence[int]) -> Group: ...
    def Range_incl(self, ranks: Sequence[Tuple[int, int, int]]) -> Group: ...
    def Range_excl(self, ranks: Sequence[Tuple[int, int, int]]) -> Group: ...
    def Free(self) -> None: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> Group: ...
    size: int
    rank: int
    Intersect = Intersection

GROUP_NULL: Final[Group] = ...
GROUP_EMPTY: Final[Group] = ...

class Info:
    def __new__(cls, info: Optional[Info] = None) -> Info: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __iter__(self) -> Iterator[str]: ...
    def __bool__(self) -> bool: ...
    def __len__(self) -> int: ...
    def __getitem__(self, item: str) -> str: ...
    def __setitem__(self, item: str, value: str) -> None: ...
    def __delitem__(self, item: str) -> None: ...
    def __contains__(self, value: str) -> bool: ...
    @classmethod
    def Create(cls) -> Info: ...
    def Free(self) -> None: ...
    def Dup(self) -> Info: ...
    def Get(self, key: str, maxlen: int = -1) -> Optional[str]: ...
    def Set(self, key: str, value: str) -> None: ...
    def Delete(self, key: str) -> None: ...
    def Get_nkeys(self) -> int: ...
    def Get_nthkey(self, n: int) -> str: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> Info: ...
    def get(self, key: str, default: Optional[str] = None) -> Optional[str]: ...
    def keys(self) -> List[str]: ...
    def values(self) -> List[str]: ...
    def items(self) -> List[Tuple[str, str]]: ...
    def update(self, other: Union[Info, Mapping[str, str], Iterable[Tuple[str, str]]] = (), **kwds: str) -> None: ...
    def pop(self, key: str, *default: str) -> str: ...
    def popitem(self) -> Tuple[str, str]: ...
    def copy(self) -> Info: ...
    def clear(self) -> None: ...

INFO_NULL: Final[Info] = ...
INFO_ENV: Final[Info] = ...

class Errhandler:
    def __new__(cls, errhandler: Optional[Errhandler] = None) -> Errhandler: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __bool__(self) -> bool: ...
    def Free(self) -> None: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> Errhandler: ...

ERRHANDLER_NULL: Final[Errhandler] = ...
ERRORS_RETURN: Final[Errhandler] = ...
ERRORS_ARE_FATAL: Final[Errhandler] = ...

class Comm:
    def __new__(cls, comm: Optional[Comm] = None) -> Comm: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __bool__(self) -> bool: ...
    def Get_group(self) -> Group: ...
    def Get_size(self) -> int: ...
    def Get_rank(self) -> int: ...
    @classmethod
    def Compare(cls, comm1: Comm, comm2: Comm) -> int: ...
    def Clone(self) -> Comm: ...
    def Dup(self, info: Optional[Info] = None) -> Comm: ...
    def Dup_with_info(self, info: Info) -> Comm: ...
    def Idup(self) -> Tuple[Comm, Request]: ...
    def Create(self, group: Group) -> Comm: ...
    def Create_group(self, group: Group, tag: int = 0) -> Comm: ...
    def Split(self, color: int = 0, key: int = 0) -> Comm: ...
    def Split_type(self, split_type: int, key: int = 0, info: Info = INFO_NULL) -> Comm: ...
    def Free(self) -> None: ...
    def Set_info(self, info: Info) -> None: ...
    def Get_info(self) -> Info: ...
    def Send(self, buf: BufSpec, dest: int, tag: int = 0) -> None: ...
    def Recv(self, buf: BufSpec, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> None: ...
    def Sendrecv(self, sendbuf: BufSpec, dest: int, sendtag: int = 0, recvbuf: BufSpec = None, source: int = ANY_SOURCE, recvtag: int = ANY_TAG, status: Optional[Status] = None) -> None: ...
    def Sendrecv_replace(self, buf: BufSpec, dest: int, sendtag: int = 0, source: int = ANY_SOURCE, recvtag: int = ANY_TAG, status: Optional[Status] = None) -> None: ...
    def Isend(self, buf: BufSpec, dest: int, tag: int = 0) -> Request: ...
    def Irecv(self, buf: BufSpec, source: int = ANY_SOURCE, tag: int = ANY_TAG) -> Request: ...
    def Probe(self, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Literal[True]: ...
    def Iprobe(self, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> bool: ...
    def Mprobe(self, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Message: ...
    def Improbe(self, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Optional[Message]: ...
    def Send_init(self, buf: BufSpec, dest: int, tag: int = 0) -> Prequest: ...
    def Recv_init(self, buf: BufSpec, source: int = ANY_SOURCE, tag: int = ANY_TAG) -> Prequest: ...
    def Bsend(self, buf: BufSpec, dest: int, tag: int = 0) -> None: ...
    def Ssend(self, buf: BufSpec, dest: int, tag: int = 0) -> None: ...
    def Rsend(self, buf: BufSpec, dest: int, tag: int = 0) -> None: ...
    def Ibsend(self, buf: BufSpec, dest: int, tag: int = 0) -> Request: ...
    def Issend(self, buf: BufSpec, dest: int, tag: int = 0) -> Request: ...
    def Irsend(self, buf: BufSpec, dest: int, tag: int = 0) -> Request: ...
    def Bsend_init(self, buf: BufSpec, dest: int, tag: int = 0) -> Request: ...
    def Ssend_init(self, buf: BufSpec, dest: int, tag: int = 0) -> Request: ...
    def Rsend_init(self, buf: BufSpec, dest: int, tag: int = 0) -> Request: ...
    def Barrier(self) -> None: ...
    def Bcast(self, buf: BufSpec, root: int = 0) -> None: ...
    def Gather(self, sendbuf: Union[BufSpec, InPlace], recvbuf: Optional[BufSpecB], root: int = 0) -> None: ...
    def Gatherv(self, sendbuf: Union[BufSpec, InPlace], recvbuf: Optional[BufSpecV], root: int = 0) -> None: ...
    def Scatter(self, sendbuf: Optional[BufSpecB], recvbuf: Union[BufSpec, InPlace], root: int = 0) -> None: ...
    def Scatterv(self, sendbuf: Optional[BufSpecV], recvbuf: Union[BufSpec, InPlace], root: int = 0) -> None: ...
    def Allgather(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpecB) -> None: ...
    def Allgatherv(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpecV) -> None: ...
    def Alltoall(self, sendbuf: Union[BufSpecB, InPlace], recvbuf: BufSpecB) -> None: ...
    def Alltoallv(self, sendbuf: Union[BufSpecV, InPlace], recvbuf: BufSpecV) -> None: ...
    def Alltoallw(self, sendbuf: Union[BufSpecW, InPlace], recvbuf: BufSpecW) -> None: ...
    def Reduce(self, sendbuf: Union[BufSpec, InPlace], recvbuf: Optional[BufSpec], op: Op = SUM, root: int = 0) -> None: ...
    def Allreduce(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpec, op: Op = SUM) -> None: ...
    def Reduce_scatter_block(self, sendbuf: Union[BufSpecB, InPlace], recvbuf: Union[BufSpec, BufSpecB], op: Op = SUM) -> None: ...
    def Reduce_scatter(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpec, recvcounts: Optional[Sequence[int]] = None, op: Op = SUM) -> None: ...
    def Ibarrier(self) -> Request: ...
    def Ibcast(self, buf: BufSpec, root: int = 0) -> Request: ...
    def Igather(self, sendbuf: Union[BufSpec, InPlace], recvbuf: Optional[BufSpecB], root: int = 0) -> Request: ...
    def Igatherv(self, sendbuf: Union[BufSpec, InPlace], recvbuf: Optional[BufSpecV], root: int = 0) -> Request: ...
    def Iscatter(self, sendbuf: Optional[BufSpecB], recvbuf: Union[BufSpec, InPlace], root: int = 0) -> Request: ...
    def Iscatterv(self, sendbuf: Optional[BufSpecV], recvbuf: Union[BufSpec, InPlace], root: int = 0) -> Request: ...
    def Iallgather(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpecB) -> Request: ...
    def Iallgatherv(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpecV) -> Request: ...
    def Ialltoall(self, sendbuf: Union[BufSpecB, InPlace], recvbuf: BufSpecB) -> Request: ...
    def Ialltoallv(self, sendbuf: Union[BufSpecV, InPlace], recvbuf: BufSpecV) -> Request: ...
    def Ialltoallw(self, sendbuf: Union[BufSpecW, InPlace], recvbuf: BufSpecW) -> Request: ...
    def Ireduce(self, sendbuf: Union[BufSpec, InPlace], recvbuf: Optional[BufSpec], op: Op = SUM, root: int = 0) -> Request: ...
    def Iallreduce(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpec, op: Op = SUM) -> Request: ...
    def Ireduce_scatter_block(self, sendbuf: Union[BufSpecB, InPlace], recvbuf: Union[BufSpec, BufSpecB], op: Op = SUM) -> Request: ...
    def Ireduce_scatter(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpec, recvcounts: Optional[Sequence[int]] = None, op: Op = SUM) -> Request: ...
    def Is_inter(self) -> bool: ...
    def Is_intra(self) -> bool: ...
    def Get_topology(self) -> int: ...
    @classmethod
    def Get_parent(cls) -> Intercomm: ...
    def Disconnect(self) -> None: ...
    @classmethod
    def Join(cls, fd: int) -> Intercomm: ...
    def Get_attr(self, keyval: int) -> Optional[Union[int, Any]]: ...
    def Set_attr(self, keyval: int, attrval: Any) -> None: ...
    def Delete_attr(self, keyval: int) -> None: ...
    @classmethod
    def Create_keyval(cls, copy_fn: Optional[Callable[[Comm, int, Any], Any]] = None, delete_fn: Optional[Callable[[Comm, int, Any], None]] = None, nopython: bool = False) -> int: ...
    @classmethod
    def Free_keyval(cls, keyval: int) -> int: ...
    def Get_errhandler(self) -> Errhandler: ...
    def Set_errhandler(self, errhandler: Errhandler) -> None: ...
    def Call_errhandler(self, errorcode: int) -> None: ...
    def Abort(self, errorcode: int = 0) -> NoReturn: ...
    def Get_name(self) -> str: ...
    def Set_name(self, name: str) -> None: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> Comm: ...
    def send(self, obj: Any, dest: int, tag: int = 0) -> None: ...
    def bsend(self, obj: Any, dest: int, tag: int = 0) -> None: ...
    def ssend(self, obj: Any, dest: int, tag: int = 0) -> None: ...
    def recv(self, buf: Optional[Buffer] = None, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Any: ...
    def sendrecv(self, sendobj: Any, dest: int, sendtag: int = 0, recvbuf: Optional[Buffer] = None, source: int = ANY_SOURCE, recvtag: int = ANY_TAG, status: Optional[Status] = None) -> Any: ...
    def isend(self, obj: Any, dest: int, tag: int = 0) -> Request: ...
    def ibsend(self, obj: Any, dest: int, tag: int = 0) -> Request: ...
    def issend(self, obj: Any, dest: int, tag: int = 0) -> Request: ...
    def irecv(self, buf: Optional[Buffer] = None, source: int = ANY_SOURCE, tag: int = ANY_TAG) -> Request: ...
    def probe(self, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Literal[True]: ...
    def iprobe(self, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> bool: ...
    def mprobe(self, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Message: ...
    def improbe(self, source: int = ANY_SOURCE, tag: int = ANY_TAG, status: Optional[Status] = None) -> Optional[Message]: ...
    def barrier(self) -> None: ...
    def bcast(self, obj: Any, root: int = 0) -> Any: ...
    def gather(self, sendobj: Any, root: int = 0) -> Optional[List[Any]]: ...
    def scatter(self, sendobj: Sequence[Any], root: int = 0) -> Any: ...
    def allgather(self, sendobj: Any) -> List[Any]: ...
    def alltoall(self, sendobj: Sequence[Any]) -> List[Any]: ...
    def reduce(self, sendobj: Any, op: Union[Op, Callable[[Any, Any], Any]] = SUM, root: int = 0) -> Optional[Any]: ...
    def allreduce(self, sendobj: Any, op: Union[Op, Callable[[Any, Any], Any]] = SUM) -> Any: ...
    group: Group
    size: int
    rank: int
    info: Info
    is_inter: bool
    is_intra: bool
    topology: int
    is_topo: bool
    name: str

COMM_NULL: Final[Comm] = ...

class Intracomm(Comm):
    def __new__(cls, comm: Optional[Comm] = None) -> Intracomm: ...
    def Create_cart(self, dims: Sequence[int], periods: Optional[Sequence[bool]] = None, reorder: bool = False) -> Cartcomm: ...
    def Create_graph(self, index: Sequence[int], edges: Sequence[int], reorder: bool = False) -> Graphcomm: ...
    def Create_dist_graph_adjacent(self, sources: Sequence[int], destinations: Sequence[int], sourceweights: Optional[Sequence[int]] = None, destweights: Optional[Sequence[int]] = None, info: Info = INFO_NULL, reorder: bool = False) -> Distgraphcomm: ...
    def Create_dist_graph(self, sources: Sequence[int], degrees: Sequence[int], destinations: Sequence[int], weights: Optional[Sequence[int]] = None, info: Info = INFO_NULL, reorder: bool = False) -> Distgraphcomm: ...
    def Create_intercomm(self, local_leader: int, peer_comm: Intracomm, remote_leader: int, tag: int = 0) -> Intercomm: ...
    def Cart_map(self, dims: Sequence[int], periods: Optional[Sequence[bool]] = None) -> int: ...
    def Graph_map(self, index: Sequence[int], edges: Sequence[int]) -> int: ...
    def Scan(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpec, op: Op = SUM) -> None: ...
    def Exscan(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpec, op: Op = SUM) -> None: ...
    def Iscan(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpec, op: Op = SUM) -> Request: ...
    def Iexscan(self, sendbuf: Union[BufSpec, InPlace], recvbuf: BufSpec, op: Op = SUM) -> Request: ...
    def scan(self, sendobj: Any, op: Union[Op, Callable[[Any, Any], Any]] = SUM) -> Any: ...
    def exscan(self, sendobj: Any, op: Union[Op, Callable[[Any, Any], Any]] = SUM) -> Any: ...
    def Spawn(self, command: str, args: Optional[Sequence[str]] = None, maxprocs: int = 1, info: Info = INFO_NULL, root: int = 0, errcodes: Optional[list] = None) -> Intercomm: ...
    def Spawn_multiple(self, command: Sequence[str], args: Optional[Sequence[Sequence[str]]] = None, maxprocs: Optional[Sequence[int]] = None, info: Union[Info, Sequence[Info]] = INFO_NULL, root: int = 0, errcodes: Optional[list] = None) -> Intercomm: ...
    def Accept(self, port_name: str, info: Info = INFO_NULL, root: int = 0) -> Intercomm: ...
    def Connect(self, port_name: str, info: Info = INFO_NULL, root: int = 0) -> Intercomm: ...

COMM_SELF: Final[Intracomm] = ...
COMM_WORLD: Final[Intracomm] = ...

class Topocomm(Intracomm):
    def __new__(cls, comm: Optional[Comm] = None) -> Topocomm: ...
    def Neighbor_allgather(self, sendbuf: BufSpec, recvbuf: BufSpecB) -> None: ...
    def Neighbor_allgatherv(self, sendbuf: BufSpec, recvbuf: BufSpecV) -> None: ...
    def Neighbor_alltoall(self, sendbuf: BufSpecB, recvbuf: BufSpecB) -> None: ...
    def Neighbor_alltoallv(self, sendbuf: BufSpecV, recvbuf: BufSpecV) -> None: ...
    def Neighbor_alltoallw(self, sendbuf: BufSpecW, recvbuf: BufSpecW) -> None: ...
    def Ineighbor_allgather(self, sendbuf: BufSpec, recvbuf: BufSpecB) -> Request: ...
    def Ineighbor_allgatherv(self, sendbuf: BufSpec, recvbuf: BufSpecV) -> Request: ...
    def Ineighbor_alltoall(self, sendbuf: BufSpecB, recvbuf: BufSpecB) -> Request: ...
    def Ineighbor_alltoallv(self, sendbuf: BufSpecV, recvbuf: BufSpecV) -> Request: ...
    def Ineighbor_alltoallw(self, sendbuf: BufSpecW, recvbuf: BufSpecW) -> Request: ...
    def neighbor_allgather(self, sendobj: Any) -> List[Any]: ...
    def neighbor_alltoall(self, sendobj: List[Any]) -> List[Any]: ...
    degrees: Tuple[int, int]
    indegree: int
    outdegree: int
    inoutedges: Tuple[List[int], List[int]]
    inedges: List[int]
    outedges: List[int]

class Cartcomm(Topocomm):
    def __new__(cls, comm: Optional[Comm] = None) -> Cartcomm: ...
    def Get_dim(self) -> int: ...
    def Get_topo(self) -> Tuple[List[int], List[int], List[int]]: ...
    def Get_cart_rank(self, coords: Sequence[int]) -> int: ...
    def Get_coords(self, rank: int) -> List[int]: ...
    def Shift(self, direction: int, disp: int) -> Tuple[int, int]: ...
    def Sub(self, remain_dims: Sequence[bool]) -> Cartcomm: ...
    dim: int
    ndim: int
    topo: Tuple[List[int], List[int], List[int]]
    dims: List[int]
    periods: List[int]
    coords: List[int]

class Graphcomm(Topocomm):
    def __new__(cls, comm: Optional[Comm] = None) -> Graphcomm: ...
    def Get_dims(self) -> Tuple[int, int]: ...
    def Get_topo(self) -> Tuple[List[int], List[int]]: ...
    def Get_neighbors_count(self, rank: int) -> int: ...
    def Get_neighbors(self, rank: int) -> List[int]: ...
    dims: Tuple[int, int]
    nnodes: int
    nedges: int
    topo: Tuple[List[int], List[int]]
    index: List[int]
    edges: List[int]
    nneighbors: int
    neighbors: List[int]

class Distgraphcomm(Topocomm):
    def __new__(cls, comm: Optional[Comm] = None) -> Distgraphcomm: ...
    def Get_dist_neighbors_count(self) -> int: ...
    def Get_dist_neighbors(self) -> Tuple[List[int], List[int], Optional[Tuple[List[int], List[int]]]]: ...

class Intercomm(Comm):
    def __new__(cls, comm: Optional[Comm] = None) -> Intercomm: ...
    def Get_remote_group(self) -> Group: ...
    def Get_remote_size(self) -> int: ...
    def Merge(self, high: bool = False) -> Intracomm: ...
    remote_group: Group
    remote_size: int

class Win:
    def __new__(cls, win: Optional[Win] = None) -> Win: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __bool__(self) -> bool: ...
    @classmethod
    def Create(cls, memory: Union[Buffer, Bottom, None], disp_unit: int = 1, info: Info = INFO_NULL, comm: Intracomm = COMM_SELF) -> Win: ...
    @classmethod
    def Allocate(cls, size: int, disp_unit: int = 1, info: Info = INFO_NULL, comm: Intracomm = COMM_SELF) -> Win: ...
    @classmethod
    def Allocate_shared(cls, size: int, disp_unit: int = 1, info: Info = INFO_NULL, comm: Intracomm = COMM_SELF) -> Win: ...
    def Shared_query(self, rank: int) -> Tuple[memory, int]: ...
    @classmethod
    def Create_dynamic(cls, info: Info = INFO_NULL, comm: Intracomm = COMM_SELF) -> Win: ...
    def Attach(self, memory: Buffer) -> None: ...
    def Detach(self, memory: Buffer) -> None: ...
    def Free(self) -> None: ...
    def Set_info(self, info: Info) -> None: ...
    def Get_info(self) -> Info: ...
    def Get_group(self) -> Group: ...
    def Get_attr(self, keyval: int) -> Optional[Union[int, Any]]: ...
    def Set_attr(self, keyval: int, attrval: Any) -> None: ...
    def Delete_attr(self, keyval: int) -> None: ...
    @classmethod
    def Create_keyval(cls, copy_fn: Optional[Callable[[Win, int, Any], Any]] = None, delete_fn: Optional[Callable[[Win, int, Any], None]] = None, nopython: bool = False) -> int: ...
    @classmethod
    def Free_keyval(cls, keyval: int) -> int: ...
    def tomemory(self) -> memory: ...
    def Put(self, origin: BufSpec, target_rank: int, target: Optional[TargetSpec] = None) -> None: ...
    def Get(self, origin: BufSpec, target_rank: int, target: Optional[TargetSpec] = None) -> None: ...
    def Accumulate(self, origin: BufSpec, target_rank: int, target: Optional[TargetSpec] = None, op: Op = SUM) -> None: ...
    def Get_accumulate(self, origin: BufSpec, result: BufSpec, target_rank: int, target: Optional[TargetSpec] = None, op: Op = SUM) -> None: ...
    def Fetch_and_op(self, origin: BufSpec, result: BufSpec, target_rank: int, target_disp: int = 0, op: Op = SUM) -> None: ...
    def Compare_and_swap(self, origin: BufSpec, compare: BufSpec, result: BufSpec, target_rank: int, target_disp: int = 0) -> None: ...
    def Rput(self, origin: BufSpec, target_rank: int, target: Optional[TargetSpec] = None) -> Request: ...
    def Rget(self, origin: BufSpec, target_rank: int, target: Optional[TargetSpec] = None) -> Request: ...
    def Raccumulate(self, origin: BufSpec, target_rank: int, target: Optional[TargetSpec] = None, op: Op = SUM) -> Request: ...
    def Rget_accumulate(self, origin: BufSpec, result: BufSpec, target_rank: int, target: Optional[TargetSpec] = None, op: Op = SUM) -> Request: ...
    def Fence(self, assertion: int = 0) -> None: ...
    def Start(self, group: Group, assertion: int = 0) -> None: ...
    def Complete(self) -> None: ...
    def Post(self, group: Group, assertion: int = 0) -> None: ...
    def Wait(self) -> Literal[True]: ...
    def Test(self) -> bool: ...
    def Lock(self, rank: int, lock_type: int = LOCK_EXCLUSIVE, assertion: int = 0) -> None: ...
    def Unlock(self, rank: int) -> None: ...
    def Lock_all(self, assertion: int = 0) -> None: ...
    def Unlock_all(self) -> None: ...
    def Flush(self, rank: int) -> None: ...
    def Flush_all(self) -> None: ...
    def Flush_local(self, rank: int) -> None: ...
    def Flush_local_all(self) -> None: ...
    def Sync(self) -> None: ...
    def Get_errhandler(self) -> Errhandler: ...
    def Set_errhandler(self, errhandler: Errhandler) -> None: ...
    def Call_errhandler(self, errorcode: int) -> None: ...
    def Get_name(self) -> str: ...
    def Set_name(self, name: str) -> None: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> Win: ...
    info: Info
    group: Group
    attrs: Tuple[int, int, int]
    flavor: int
    model: int
    name: str

WIN_NULL: Final[Win] = ...

class File:
    def __new__(cls, file: Optional[File] = None) -> File: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __bool__(self) -> bool: ...
    @classmethod
    def Open(cls, comm: Intracomm, filename: str, amode: int = MODE_RDONLY, info: Info = INFO_NULL) -> File: ...
    def Close(self) -> None: ...
    @classmethod
    def Delete(cls, filename: str, info: Info = INFO_NULL) -> None: ...
    def Set_size(self, size: int) -> None: ...
    def Preallocate(self, size: int) -> None: ...
    def Get_size(self) -> int: ...
    def Get_amode(self) -> int: ...
    def Get_group(self) -> Group: ...
    def Set_info(self, info: Info) -> None: ...
    def Get_info(self) -> Info: ...
    def Set_view(self, disp: int = 0, etype: Datatype = BYTE, filetype: Optional[Datatype] = None, datarep: str = 'native', info: Info = INFO_NULL) -> None: ...
    def Get_view(self) -> Tuple[int, Datatype, Datatype, str]: ...
    def Read_at(self, offset: int, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Read_at_all(self, offset: int, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Write_at(self, offset: int, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Write_at_all(self, offset: int, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Iread_at(self, offset: int, buf: BufSpec) -> Request: ...
    def Iread_at_all(self, offset: int, buf: BufSpec) -> Request: ...
    def Iwrite_at(self, offset: int, buf: BufSpec) -> Request: ...
    def Iwrite_at_all(self, offset: int, buf: BufSpec) -> Request: ...
    def Read(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Read_all(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Write(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Write_all(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Iread(self, buf: BufSpec) -> Request: ...
    def Iread_all(self, buf: BufSpec) -> Request: ...
    def Iwrite(self, buf: BufSpec) -> Request: ...
    def Iwrite_all(self, buf: BufSpec) -> Request: ...
    def Seek(self, offset: int, whence: int = SEEK_SET) -> None: ...
    def Get_position(self) -> int: ...
    def Get_byte_offset(self, offset: int) -> int: ...
    def Read_shared(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Write_shared(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Iread_shared(self, buf: BufSpec) -> Request: ...
    def Iwrite_shared(self, buf: BufSpec) -> Request: ...
    def Read_ordered(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Write_ordered(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Seek_shared(self, offset: int, whence: int = SEEK_SET) -> None: ...
    def Get_position_shared(self) -> int: ...
    def Read_at_all_begin(self, offset: int, buf: BufSpec) -> None: ...
    def Read_at_all_end(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Write_at_all_begin(self, offset: int, buf: BufSpec) -> None: ...
    def Write_at_all_end(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Read_all_begin(self, buf: BufSpec) -> None: ...
    def Read_all_end(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Write_all_begin(self, buf: BufSpec) -> None: ...
    def Write_all_end(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Read_ordered_begin(self, buf: BufSpec) -> None: ...
    def Read_ordered_end(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Write_ordered_begin(self, buf: BufSpec) -> None: ...
    def Write_ordered_end(self, buf: BufSpec, status: Optional[Status] = None) -> None: ...
    def Get_type_extent(self, datatype: Datatype) -> int: ...
    def Set_atomicity(self, flag: bool) -> None: ...
    def Get_atomicity(self) -> bool: ...
    def Sync(self) -> None: ...
    def Get_errhandler(self) -> Errhandler: ...
    def Set_errhandler(self, errhandler: Errhandler) -> None: ...
    def Call_errhandler(self, errorcode: int) -> None: ...
    def py2f(self) -> int: ...
    @classmethod
    def f2py(cls, arg: int) -> File: ...
    size: int
    amode: int
    group: Group
    info: Info
    atomicity: bool

FILE_NULL: Final[File] = ...

class memory:
    @overload
    def __new__(cls) -> memory: ...
    @overload
    def __new__(cls, buf: Buffer, /) -> memory: ...
    def __len__(self) -> int: ...
    @overload
    def __getitem__(self, item: int) -> int: ...
    @overload
    def __getitem__(self, item: slice) -> memory: ...
    @overload
    def __setitem__(self, item: int, value: int) -> None: ...
    @overload
    def __setitem__(self, item: slice, value: Buffer) -> None: ...
    @staticmethod
    def allocate(nbytes: int, clear: bool = False) -> memory: ...
    @staticmethod
    def frombuffer(obj: Buffer, readonly: bool = False) -> memory: ...
    @staticmethod
    def fromaddress(address: int, nbytes: int, readonly: bool = False) -> memory: ...
    def tobytes(self, order: Optional[str] = None) -> bytes: ...
    def toreadonly(self) -> memory: ...
    def release(self) -> None: ...
    address: int
    obj: Optional[Buffer]
    nbytes: int
    readonly: bool
    format: str
    itemsize: int

class Pickle:
    @overload
    def __init__(self,
        dumps: Callable[[Any, int], bytes],
        loads: Callable[[Buffer], Any],
        protocol: Optional[int] = None,
    ) -> None: ...
    @overload
    def __init__(self,
        dumps: Optional[Callable[[Any], bytes]] = None,
        loads: Optional[Callable[[Buffer], Any]] = None,
    ) -> None: ...
    def dumps(self, obj: Any, buffer_callback: Optional[Callable[[Buffer], Any]] = None) -> bytes: ...
    def loads(self, data: Buffer, buffers: Optional[Iterable[Buffer]] = None) -> Any: ...
    PROTOCOL: Optional[int]

pickle: Final[Pickle] = ...

class Exception(RuntimeError):
    def __init__(self, ierr: int = SUCCESS) -> None: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __hash__(self) -> int: ...
    def __bool__(self) -> bool: ...
    def __int__(self) -> int: ...
    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...
    def Get_error_code(self) -> int: ...
    error_code: int
    def Get_error_class(self) -> int: ...
    error_class: int
    def Get_error_string(self) -> str: ...
    error_string: str

def Get_error_class(errorcode: int) -> int: ...
def Get_error_string(errorcode: int) -> str: ...
def Add_error_class() -> int: ...
def Add_error_code(errorclass: int) -> int: ...
def Add_error_string(errorcode: int, string: str) -> None: ...
def Get_address(location: Union[Buffer, Bottom]) -> int: ...
def Aint_add(base: int, disp: int) -> int: ...
def Aint_diff(addr1: int, addr2: int) -> int: ...
def Compute_dims(nnodes: int, dims: Union[int, Sequence[int]]) -> List[int]: ...
def Attach_buffer(buf: Buffer) -> None: ...
def Detach_buffer() -> Buffer: ...
def Open_port(info: Info = INFO_NULL) -> str: ...
def Close_port(port_name: str) -> None: ...
def Publish_name(service_name: str, port_name: str, info: Info = INFO_NULL) -> None: ...
def Unpublish_name(service_name: str, port_name: str, info: Info = INFO_NULL) -> None: ...
def Lookup_name(service_name: str, info: Info = INFO_NULL) -> str: ...
def Register_datarep(datarep: str, read_fn: Callable[[Buffer, Datatype, int, Buffer, int], None], write_fn: Callable[[Buffer, Datatype, int, Buffer, int], None], extent_fn: Callable[[Datatype], int]) -> None: ...
def Alloc_mem(size: int, info: Info = INFO_NULL) -> memory: ...
def Free_mem(mem: memory) -> None: ...
def Init() -> None: ...
def Finalize() -> None: ...
def Init_thread(required: int = THREAD_MULTIPLE) -> int: ...
def Query_thread() -> int: ...
def Is_thread_main() -> bool: ...
def Is_initialized() -> bool: ...
def Is_finalized() -> bool: ...
def Get_version() -> Tuple[int, int]: ...
def Get_library_version() -> str: ...
def Get_processor_name() -> str: ...
def Wtime() -> float: ...
def Wtick() -> float: ...
def Pcontrol(level: int) -> None: ...
def get_vendor() -> Tuple[str, Tuple[int, int, int]]: ...
def _set_abort_status(status: Any) -> None: ...
def _comm_lock(comm: Comm, key: Hashable = None) -> Lock: ...
def _comm_lock_table(comm: Comm) -> Dict[Hashable, Lock]: ...
_lock_table = _comm_lock_table
def _commctx_intra(comm: Intracomm) -> Tuple[Intracomm, int]: ...
def _commctx_inter(comm: Intercomm) -> Tuple[Intercomm, int, Intracomm, bool]: ...
def _typecode(datatype: Datatype) -> Optional[str]: ...
def _sizeof(arg: Any) -> int: ...
def _addressof(arg: Any) -> int: ...
def _handleof(arg: Any) -> int: ...

_typedict: Final[Dict[str, Datatype]] = ...
_typedict_c: Final[Dict[str, Datatype]] = ...
_typedict_f: Final[Dict[str, Datatype]] = ...

Buffer = Any  # TODO

Count = int
Displ = int
TypeSpec = Union[Datatype, str]

BufSpec = Union[
    Buffer,
    Tuple[Buffer, Count],            # (buffer, count)
    Tuple[Buffer, TypeSpec],         # (buffer, datatype)
    Tuple[Buffer, Count, TypeSpec],  # (buffer, count, datatype)
    Tuple[Bottom, Count, Datatype],  # (BOTTOM, count, datatype)
    List,                            # (buffer, count, datatype)
]

BufSpecB = Union[
    Buffer,
    Tuple[Buffer, TypeSpec],         # (buffer, datatype)
    Tuple[Buffer, Count, TypeSpec],  # (buffer, count, datatype)
    List,                            # (buffer, count, datatype)
]

BufSpecV = Union[
    Buffer,
    Tuple[Buffer, Sequence[Count]],                                    # (buffer, counts)
    Tuple[Buffer, Tuple[Sequence[Count], Sequence[Displ]]],            # (buffer, (counts, displs))
    Tuple[Buffer, TypeSpec],                                           # (buffer, datatype)
    Tuple[Buffer, Sequence[Count], TypeSpec],                          # (buffer, counts, datatype)
    Tuple[Buffer, Tuple[Sequence[Count], Sequence[Displ]], TypeSpec],  # (buffer, (counts, displs), datatype)
    Tuple[Buffer, Sequence[Count], Sequence[Displ], TypeSpec],         # (buffer, counts, displs, datatype)
    Tuple[Bottom, Tuple[Sequence[Count], Sequence[Displ]], Datatype],  # (BOTTOM, (counts, displs), datatype)
    Tuple[Bottom, Sequence[Count], Sequence[Displ], Datatype],         # (BOTTOM, counts, displs, datatype)
    List,                                                              # (buffer, counts, displs, datatypes)
]

BufSpecW = Union[
    Tuple[Buffer, Sequence[Datatype]],                                           # (buffer, datatypes)
    Tuple[Buffer, Tuple[Sequence[Count], Sequence[Displ]], Sequence[Datatype]],  # (buffer, (counts, displs), datatypes)
    Tuple[Buffer, Sequence[Count], Sequence[Displ], Sequence[Datatype]],         # (buffer, counts, displs, datatypes)
    Tuple[Bottom, Tuple[Sequence[Count], Sequence[Displ]], Sequence[Datatype]],  # (BOTTOM, (counts, displs), datatypes)
    Tuple[Bottom, Sequence[Count], Sequence[Displ], Sequence[Datatype]],         # (BOTTOM, counts, displs, datatypes)
    List,                                                                        # (buffer, counts, displs, datatypes)
]

TargetSpec = Union[
    Displ,                          # displ
    Tuple[()],                      # ()
    Tuple[Displ],                   # (displ,)
    Tuple[Displ, Count],            # (displ, count)
    Tuple[Displ, Count, Datatype],  # (displ, count, datatype)
    List,                           # (displ, count, datatype)
]
