MPI4PY(3)
๐ MPI4PY โ the manual, but make it make sense ๐
okay bestie, welcome to the MPI for Python page, aka MPI4PY(3), sitting pretty in the MPI for Python corner of the manual. pull up a chair, grab a boba, we're doing this together ๐ซถ
Author: Lisandro Dalcin Contact: <dalcinl@gmail.com> Date: March 20, 2026
๐ Abstract ๐
okay so real talk: MPI for Python gives you Python bindings for the Message Passing Interface (MPI) standard. the whole point? letting your Python apps go absolutely feral across multiple processors on workstations, clusters, and supercomputers. slay. ๐
this package is built on top of the MPI specification and serves up an object oriented interface that's giving major MPI-2 C++ bindings energy. it handles:
- point-to-point stuff (sends, receives) โ๏ธ
- collective stuff (broadcasts, scatters, gathers) ๐ข
- communication of any picklable Python object
- efficient communication of Python objects that expose the Python buffer interface โ think NumPy arrays, plus builtin
bytes/array/memoryviewobjects ๐
๐ INTRODUCTION ๐
so over the last few years, high performance computing went from "only the cool kids with money" to actually affordable for way more researchers in the scientific community than ever before. the combo of quality open source software + commodity hardware is literally why Beowulf <https://www.beowulf.org/> class clusters and cluster of workstations are so popular now. iconic behavior fr fr.
out of all the parallel computational models out there, message-passing has proven itself to be a genuinely effective one. this paradigm is especially suited for (but not limited to!!) distributed memory architectures, and it's used in today's most demanding scientific and engineering applications โ modeling, simulation, design, signal processing, the whole vibe. but here's the tea: portable message-passing parallel programming used to be an actual nightmare because of all the incompatible options devs were stuck with. fortunately, that whole situation changed for good once the MPI Forum dropped its standard specification. โจ
high performance computing is traditionally associated with software development using compiled languages. but bestie, in typical application programs, only a small part of the code is actually time-critical enough to need the efficiency of compiled languages. the rest is generally about memory management, error handling, input/output, and user interaction โ and those are usually the most error prone and time-consuming lines to write and debug in the entire development process. interpreted high-level languages can be really advantageous for this kind of task.
for implementing general-purpose numerical computations, MATLAB [1] is the dominant interpreted programming language. on the open source side, Octave and Scilab are well known, freely distributed packages providing compatibility with the MATLAB language. in this work, we present MPI for Python โ a new package enabling applications to exploit multiple processors using standard MPI "look and feel" in Python scripts. ๐
[1] MATLAB is a registered trademark of The MathWorks, Inc.
๐ฆ What is MPI? ๐ฆ
MPI <https://www.mpi-forum.org/>, [mpi-using] <#mpi-using> [mpi-ref] <#mpi-ref> โ the Message Passing Interface โ is a standardized and portable message-passing system designed to function on a wide variety of parallel computers. the standard defines the syntax and semantics of library routines and lets users write portable programs in the main scientific programming languages (Fortran, C, or C++).
since its release, the MPI specification [mpi-std1] <#mpi-std1> [mpi-std2] <#mpi-std2> has become the leading standard for message-passing libraries for parallel computers. implementations are available from vendors of high-performance computers and from well known open source projects like MPICH <https://www.mpich.org/> [mpi-mpich] <#mpi-mpich> and Open MPI <https://www.open-mpi.org/> [mpi-openmpi] <#mpi-openmpi>. ๐
๐ธ What is Python? ๐ธ
Python <https://www.python.org/> is a modern, easy to learn, powerful programming language. it has efficient high-level data structures and a simple but effective approach to object-oriented programming with dynamic typing and dynamic binding. it supports modules and packages, which encourages program modularity and code reuse. Python's elegant syntax, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms.
the Python interpreter and the extensive standard library are available in source or binary form without charge for all major platforms, and can be freely distributed. it's easily extended with new functions and data types implemented in C or C++. Python is also suitable as an extension language for customizable applications.
Python is an ideal candidate for writing the higher-level parts of large-scale scientific applications [Hinsen97] <#hinsen97> and driving simulations in parallel architectures [Beazley97] <#beazley97> like clusters of PC's or SMP's. Python codes are quickly developed, easily maintained, and can achieve a high degree of integration with other libraries written in compiled languages. ๐โจ
๐ง Related Projects ๐ง
as this work started and evolved, some ideas were borrowed from well known MPI and Python related open source projects from the Internet. credit where credit is due, bestie ๐ซถ
- OOMPI <https://web.archive.org/web/20100614170656/http://www.osl.iu.edu/research/oompi/overview.php>
- it has no relation with Python, but is an excellent object oriented approach to MPI.
- it's a C++ class library specification layered on top of the C bindings that encapsulates MPI into a functional class hierarchy.
- it provides a flexible and intuitive interface by adding some abstractions, like Ports and Messages, which enrich and simplify the syntax.
- Pypar <https://github.com/daleroberts/pypar>
- its interface is rather minimal. there is no support for communicators or process topologies.
- it does not require the Python interpreter to be modified or recompiled, but does not permit interactive parallel runs.
- general (picklable) Python objects of any type can be communicated. there is good support for numeric arrays, practically full MPI bandwidth can be achieved. ๐ฅ
- pyMPI <https://sourceforge.net/projects/pympi/>
- it rebuilds the Python interpreter providing a built-in module for message passing. it does permit interactive parallel runs, which are useful for learning and debugging.
- it provides an interface suitable for basic parallel programming. there is not full support for defining new communicators or process topologies.
- general (picklable) Python objects can be messaged between processors. there is native support for numeric arrays.
- Scientific Python <http://dirac.cnrs-orleans.fr/ScientificPython.html>
- it provides a collection of Python modules that are useful for scientific computing.
- there is an interface to MPI and BSP (Bulk Synchronous Parallel programming).
- the interface is simple but incomplete and does not resemble the MPI specification. there is support for numeric arrays.
additionally, we would like to mention some available tools for scientific computing and software development with Python. โจ
- NumPy <https://numpy.org/> is a package that provides array manipulation and computational capabilities similar to those found in IDL, MATLAB, or Octave. using NumPy, it is possible to write many efficient numerical data processing applications directly in Python without using any C, C++ or Fortran code.
- SciPy <https://scipy.org/> is an open source library of scientific tools for Python, gathering a variety of high level science and engineering modules together as a single package. it includes modules for graphics and plotting, optimization, integration, special functions, signal and image processing, genetic algorithms, ODE solvers, and others.
- Cython <https://cython.org/> is a language that makes writing C extensions for the Python language as easy as Python itself. the Cython language is very close to the Python language, but Cython additionally supports calling C functions and declaring C types on variables and class attributes. this allows the compiler to generate very efficient C code from Cython code. this makes Cython the ideal language for wrapping for external C libraries, and for fast C modules that speed up the execution of Python code.
- SWIG <https://www.swig.org/> is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages like Perl, Tcl/Tk, Ruby and Python. issuing header files to SWIG is the simplest approach to interfacing C/C++ libraries from a Python module.
๐ the references, aka the receipts ๐
- [mpi-std1] โ MPI Forum. MPI: A Message Passing Interface Standard. International Journal of Supercomputer Applications, volume 8, number 3-4, pages 159-416, 1994.
- [mpi-std2] โ MPI Forum. MPI: A Message Passing Interface Standard. High Performance Computing Applications, volume 12, number 1-2, pages 1-299, 1998.
- [mpi-using] โ William Gropp, Ewing Lusk, and Anthony Skjellum. Using MPI: portable parallel programming with the message-passing interface. MIT Press, 1994.
- [mpi-ref] โ Mark Snir, Steve Otto, Steven Huss-Lederman, David Walker, and Jack Dongarra. MPI - The Complete Reference, volume 1, The MPI Core. MIT Press, 2nd. edition, 1998.
- [mpi-mpich] โ W. Gropp, E. Lusk, N. Doss, and A. Skjellum. A high-performance, portable implementation of the MPI message passing interface standard. Parallel Computing, 22(6):789-828, September 1996.
- [mpi-openmpi] โ Edgar Gabriel, Graham E. Fagg, George Bosilca, Thara Angskun, Jack J. Dongarra, Jeffrey M. Squyres, Vishal Sahay, Prabhanjan Kambadur, Brian Barrett, Andrew Lumsdaine, Ralph H. Castain, David J. Daniel, Richard L. Graham, and Timothy S. Woodall. Open MPI: Goals, Concept, and Design of a Next Generation MPI Implementation. In Proceedings, 11th European PVM/MPI Users' Group Meeting, Budapest, Hungary, September 2004.
- [Hinsen97] โ Konrad Hinsen. The Molecular Modelling Toolkit: a case study of a large scientific application in Python. In Proceedings of the 6th International Python Conference, pages 29-35, San Jose, Ca., October 1997.
- [Beazley97] โ David M. Beazley and Peter S. Lomdahl. Feeding a large-scale physics application to Python. In Proceedings of the 6th International Python Conference, pages 21-29, San Jose, Ca., October 1997.
๐ OVERVIEW ๐
okay bestie, buckle UP โ MPI for Python gives you an object oriented way to do message passing, and it's built on top of the standard MPI-2 C++ bindings. The whole interface was designed with one mission: translating the syntax and semantics of those standard MPI-2 C++ bindings straight into Python. So if you already know the standard C/C++ MPI bindings, you can justโฆ use this module. No new interface to learn, periodt. ๐
๐ Communicating Python Objects and Array Data
The Python standard library has a bunch of different mechanisms for data persistence. A lot of them lean on disk storage, but pickling and marshaling can also work with memory buffers. โจ
The pickle module gives you user-extensible facilities to serialize general Python objects using ASCII or binary formats. The marshal module gives you facilities to serialize built-in Python objects using a binary format that's specific to Python, but independent of machine architecture issues. ๐
MPI for Python can communicate any built-in or user-defined Python object by taking advantage of the features the pickle module provides. These facilities get routinely used to build binary representations of objects to communicate (that's the sending process's job), and to restore them back (that's the receiving process's job). ๐
Now โ as simple and general as that serialization approach (i.e. pickling and unpickling) is, it imposes important overheads in memory as well as processor usage, especially when the objects being communicated have large memory footprints. Pickling general Python objects โ anything from primitive or container built-in types up to user-defined classes โ necessarily eats computer resources. You also need processing power to dispatch the appropriate serialization method (which depends on the object's type) and to do the actual packing. Additional memory is always needed, and if its total amount isn't known a priori, you can get many reallocations. ๐ And for large numeric arrays? Yeah, that's just straight-up unacceptable, and it precludes communication of objects occupying half or more of the available memory resources. Not the vibe. ๐ญ
Here's the glow-up: MPI for Python supports direct communication of any object exporting the single-segment buffer interface. That interface is a standard Python mechanism provided by some types (e.g. strings and numeric arrays), and it lets the C side access a contiguous memory buffer (i.e. address and length) holding the relevant data. Combine that with the ability to construct user-defined MPI datatypes describing complicated memory layouts, and you can implement so many algorithms involving multidimensional numeric arrays โ image processing, fast Fourier transforms, finite difference schemes on structured Cartesian grids, the whole lineup โ directly in Python, with negligible overhead, and almost as fast as compiled Fortran, C, or C++ codes. ๐ฅ slay.
๐ Communicators
In MPI for Python, Comm is the base class of communicators. The Intracomm and Intercomm classes are subclasses of the Comm class. The Comm.Is_inter method (and Comm.Is_intra, provided for convenience but not part of the MPI specification) is defined for communicator objects, and you can use it to figure out the particular communicator class. ๐ต๏ธโโ๏ธ
There are two predefined intracommunicator instances ready for you: COMM_SELF and COMM_WORLD. From those, you can create new communicators whenever you need them. ๐ฑ
Want the number of processes in a communicator, or the calling process rank? That's Comm.Get_size and Comm.Get_rank respectively. The associated process group comes from calling Comm.Get_group, which returns an instance of the Group class. Set operations with Group objects like Group.Union, Group.Intersection and Group.Difference are fully supported, and so is creating new communicators from those groups using Comm.Create and Intracomm.Create_group. ๐ซถ
New communicator instances can come from the Comm.Clone, Comm.Dup and Comm.Split methods, plus the Intracomm.Create_intercomm and Intercomm.Merge methods. So many doors, bestie. ๐ชโจ
Virtual topologies are fully supported too โ that's the Cartcomm, Graphcomm and Distgraphcomm classes, which are specializations of the Intracomm class. You get new instances from intracommunicator instances with the factory methods Intracomm.Create_cart and Intracomm.Create_graph. ๐บ๏ธ
๐ Point-to-Point Communications
Point to point communication is a fundamental capability of message passing systems. This mechanism enables the transmission of data between a pair of processes: one side sending, the other receiving. ๐
MPI provides a set of send and receive functions that let you communicate typed data with an associated tag. The type information enables conversion of data representation from one architecture to another in heterogeneous computing environments โ and bonus, it allows the representation of non-contiguous data layouts and user-defined datatypes, so you skip the overhead of the (otherwise unavoidable) packing/unpacking operations. The tag information lets the receiving end be selective about which messages it picks up. ๐ฏ
๐ Blocking Communications
MPI provides basic send and receive functions that are blocking. These functions block the caller until the data buffers involved in the communication can be safely reused by the application program. Like, actually wait. โณ
In MPI for Python, the Comm.Send, Comm.Recv and Comm.Sendrecv methods of communicator objects provide support for blocking point-to-point communications within Intracomm and Intercomm instances. These methods can communicate memory buffers. The variants Comm.send, Comm.recv and Comm.sendrecv can communicate general Python objects. ๐งธ
โก Nonblocking Communications
On many systems, performance can be significantly increased by overlapping communication and computation. This is especially true on systems where communication can be executed autonomously by an intelligent, dedicated communication controller. ๐ค
MPI provides nonblocking send and receive functions. They allow the possible overlap of communication and computation. Non-blocking communication always comes in two parts: posting functions, which begin the requested operation; and test-for-completion functions, which let you discover whether the requested operation has completed. ๐
In MPI for Python, the Comm.Isend and Comm.Irecv methods initiate send and receive operations, respectively. These methods return a Request instance that uniquely identifies the started operation. Its completion can be managed using the Request.Test, Request.Wait, and Request.Cancel methods. But listen โ managing Request objects and the associated memory buffers involved in communication requires a careful, rather low-level coordination. Users must ensure that objects exposing their memory buffers are not accessed at the Python level while they're involved in nonblocking message-passing operations. ๐จ
bestie this is the part where you actually pay attention: no touching the buffer while it's mid-flight, okay? ๐
๐ Persistent Communications
Often a communication with the same argument list gets repeatedly executed inside an inner loop. In those cases, communication can be further optimized by using persistent communication โ a particular case of nonblocking communication that allows the reduction of the overhead between processes and communication controllers. And furthermore, this kind of optimization can also alleviate the extra call overheads associated with interpreted, dynamic languages like Python. ๐๐จ
In MPI for Python, the Comm.Send_init and Comm.Recv_init methods create persistent requests for a send and receive operation, respectively. These methods return an instance of the Prequest class, a subclass of the Request class. The actual communication can be effectively started using the Prequest.Start method, and its completion can be managed as previously described. ๐
๐ Collective Communications
Collective communications allow the transmittal of data between multiple processes of a group simultaneously. The syntax and semantics of collective functions is consistent with point-to-point communication. Collective functions communicate typed data, but messages are not paired with an associated tag; selectivity of messages is implied in the calling order. ๐
The more commonly used collective communication operations are the following.
- Barrier synchronization across all group members. ๐งฑ
- Global communication functions
- Broadcast data from one member to all members of a group. ๐ข
- Gather data from all members to one member of a group. ๐งบ
- Scatter data from one member to all members of a group. ๐ธ
- Global reduction operations such as sum, maximum, minimum, etc. โ
Okay so let's talk collectives, because this is where mpi4py really ate ๐
. When you wanna sling memory buffers around the whole squad at once, Comm.Bcast, Comm.Scatter, Comm.Gather, Comm.Allgather, and Comm.Alltoall have you covered ๐. And if your data isn't a plain buffer but a whole general Python object? The lower-case girlies Comm.bcast, Comm.scatter, Comm.gather, Comm.allgather, and Comm.alltoall handle that, no cap โจ.
Then there's the vector variants โ these ones can send different amounts of data to each process, which is honestly so thoughtful of them ๐ซถ โ and those are Comm.Scatterv, Comm.Gatherv, Comm.Allgatherv, Comm.Alltoallv, and Comm.Alltoallw. Small catch though: they can only communicate objects exposing memory buffers. No random Python objects, sorry bestie ๐ญ.
Global reduction operations on memory buffers? Those come at you through Comm.Reduce, Comm.Reduce_scatter, Comm.Allreduce, Intracomm.Scan, and Intracomm.Exscan ๐. And their lower-case twins Comm.reduce, Comm.allreduce, Intracomm.scan, and Intracomm.exscan can pass general Python objects around, but heads up โ the actual reduction computations required get performed sequentially at some process, so it's giving "convenient but not the scalability flex you were hoping for" ๐. Also, every single predefined reduction operation (SUM, PROD, MAX, etc.) can be applied. Periodt ๐.
๐ Support for GPU-aware MPI ๐
Several MPI implementations โ Open MPI and MVAPICH included โ support passing GPU pointers straight into MPI calls, which means you get to skip the whole explicit data movement between host and device thing entirely ๐ฆ. On the Python side, support for handling GPU arrays has already been implemented in a bunch of GPU-computation libraries like CuPy, Numba, PyTorch, and PyArrow ๐.
And because interoperability across library boundaries is the moment, two kinds of zero-copy data exchange protocols have been defined and agreed upon: DLPack and CUDA Array Interface (CAI) โจ.
MPI for Python provides an experimental support for GPU-aware MPI. This feature requires:
- mpi4py is built against a GPU-aware MPI library.
- The Python GPU arrays are compliant with either of the protocols.
See the Tutorial section for further information. We note that:
- Whether or not a MPI call can work for GPU arrays depends on the underlying MPI implementation, not on mpi4py ๐.
- This support is currently experimental and subject to change in the future.
So like... don't build your whole personality on it yet, bestie ๐.
๐ Dynamic Process Management ๐
In the context of the MPI-1 specification, a parallel application is static โ meaning no processes can be added to or deleted from a running application after it has been started ๐ฅฒ. Fortunately, this limitation got addressed in MPI-2, and the new specification added a process management model providing a basic interface between an application and external resources and process managers ๐ซ.
This MPI-2 extension can be really useful, especially for sequential applications built on top of parallel modules, or parallel applications with a client/server model. The MPI-2 process model gives you a mechanism to create new processes and establish communication between them and the existing MPI application ๐ฏ. It also provides mechanisms to establish communication between two existing MPI applications, even when one did not start the other. Iconic behaviour, honestly.
In MPI for Python, new independent process groups can be created by calling the Intracomm.Spawn method within an intracommunicator. This call returns a new intercommunicator (i.e., an Intercomm instance) at the parent process group ๐. The child process group can retrieve the matching intercommunicator by calling the Comm.Get_parent class method. At each side, the new intercommunicator can be used to perform point to point and collective communications between the parent and child groups of processes ๐ซถ.
Alternatively, disjoint groups of processes can establish communication using a client/server approach. Any server application must first call the Open_port function to open a port and the Publish_name function to publish a provided service, and next call the Intracomm.Accept method ๐. Any client applications can first find a published service by calling the Lookup_name function, which returns the port where a server can be contacted; and next call the Intracomm.Connect method. Both Intracomm.Accept and Intracomm.Connect methods return an Intercomm instance ๐ธ.
When connection between client/server processes is no longer needed, all of them must cooperatively call the Comm.Disconnect method โ it's a group project, you can't just ghost ๐ค. Additionally, server applications should release resources by calling the Unpublish_name and Close_port functions ๐งน.
๐ฎ One-Sided Communications ๐ฎ
One-sided communications (also called Remote Memory Access, or RMA) supplements the traditional two-sided, send/receive based MPI communication model with a one-sided, put/get based interface ๐. One-sided communication that can take advantage of the capabilities of highly specialized network hardware. Additionally, this extension lowers latency and software overhead in applications written using a shared-memory-like paradigm โก.
The MPI specification revolves around the use of objects called windows; they intuitively specify regions of a process's memory that have been made available for remote read and write operations ๐ช. The published memory blocks can be accessed through three functions for put (remote send), get (remote write), and accumulate (remote update or reduction) data items. A much larger number of functions support different synchronization styles; the semantics of these synchronization operations are fairly complex, ngl ๐.
In MPI for Python, one-sided operations are available by using instances of the Win class ๐. New window objects are created by calling the Win.Create method at all processes within a communicator and specifying a memory buffer. When a window instance is no longer needed, the Win.Free method should be called ๐งน.
The three one-sided MPI operations for remote write, read and reduction are available through calling the methods Win.Put, Win.Get, and Win.Accumulate respectively within a Win instance โจ. These methods need an integer rank identifying the target process and an integer offset relative the base address of the remote memory block being accessed ๐.
The one-sided operations read, write, and reduction are implicitly nonblocking, and must be synchronized by using two primary modes ๐ฐ๏ธ. Active target synchronization requires the origin process to call the Win.Start and Win.Complete methods at the origin process, and target process cooperates by calling the Win.Post and Win.Wait methods ๐ค. There is also a collective variant provided by the Win.Fence method. Passive target synchronization is more lenient โ only the origin process calls the Win.Lock and Win.Unlock methods ๐. Locks are used to protect remote accesses to the locked remote window and to protect local load/store accesses to a locked local window.
๐ Parallel Input/Output ๐
The POSIX standard provides a model of a widely portable file system ๐๏ธ. However, the optimization needed for parallel input/output cannot be achieved with this generic interface ๐ญ. In order to ensure efficiency and scalability, the underlying parallel input/output system must provide a high-level interface supporting partitioning of file data among processes and a collective interface supporting complete transfers of global data structures between process memories and files ๐ซ. Additionally, further efficiencies can be gained via support for asynchronous input/output, strided accesses to data, and control over physical file layout on storage devices. This scenario motivated the inclusion in the MPI-2 standard of a custom interface in order to support more elaborated parallel input/output operations ๐ธ.
The MPI specification for parallel input/output revolves around the use objects called files. As defined by MPI, files are not just contiguous byte streams ๐ซ. Instead, they are regarded as ordered collections of typed data items. MPI supports sequential or random access to any integral set of these items. Furthermore, files are opened collectively by a group of processes ๐ฏ.
The common patterns for accessing a shared file (broadcast, scatter, gather, reduction) is expressed by using user-defined datatypes ๐. Compared to the communication patterns of point-to-point and collective communications, this approach has the advantage of added flexibility and expressiveness โจ. Data access operations (read and write) are defined for different kinds of positioning (using explicit offsets, individual file pointers, and shared file pointers), coordination (non-collective and collective), and synchronism (blocking, nonblocking, and split collective with begin/end phases) ๐.
In MPI for Python, all MPI input/output operations are performed through instances of the File class ๐. File handles are obtained by calling the File.Open method at all processes within a communicator and providing a file name and the intended access mode ๐. After use, they must be closed by calling the File.Close method. Files even can be deleted by calling method File.Delete ๐๏ธ.
After creation, files are typically associated with a per-process view ๐. The view defines the current set of data visible and accessible from an open file as an ordered set of elementary datatypes. This data layout can be set and queried with the File.Set_view and File.Get_view methods respectively ๐ฆ.
okay so the actual reading and writing?? that's done by a whole vibe of methods that mix read and write calls together, and they all behave differently depending on positioning, coordination, and synchronism. summing up the tea: MPI for Python hands you the thirty (30) methods defined in MPI-2 for reading from or writing to files, using either explicit offsets or file pointers (individual or shared), and in blocking or nonblocking and collective or noncollective versions. yes bestie, thirty. count them. ๐
๐ซถ ENVIRONMENTAL MANAGEMENT ๐ซถ
โจ Initialization and Exit โจ
so the module functions Init and Init_thread and Finalize handle MPI initialization and finalization respectively โ like, they're the ones doing the setup and the shutdown. and the module functions Is_initialized and Is_finalized give you the respective tests for initialization and finalization. iykyk. ๐ธ
Note:MPI_Init()orMPI_Init_thread()is actually called when youimporttheMPImodule from thempi4pypackage, but only if MPI is not already initialized. In such case, callingInitorInit_threadfrom Python is expected to generate an MPI error, and in turn an exception will be raised. so like, don't double-init, bestie, she will yell at you. ๐ญ
Note:MPI_Finalize()is registered (by using Python C/API functionPy_AtExit()) for being automatically called when Python processes exit, but only ifmpi4pyactually initialized MPI. Therefore, there is no need to callFinalizefrom Python to ensure MPI finalization. she cleans up after herself, periodt. ๐ง
๐ Implementation Information ๐
- The MPI version number can be retrieved from module function
Get_version. It returns a two-integer tuple(version, subversion). cute little pair fr fr. - The
Get_processor_namefunction can be used to access the processor name. iconic. - The values of predefined attributes attached to the world communicator can be obtained by calling the
Comm.Get_attrmethod within theCOMM_WORLDinstance. yes, the whole world, literally. ๐
โฐ Timers โฐ
MPI timer functionalities are available through the Wtime and Wtick functions. ticking away like a little clock emoji bestie ๐โจ
๐จ Error Handling ๐จ
In order to facilitate handle sharing with other Python modules interfacing MPI-based parallel libraries, the predefined MPI error handlers ERRORS_RETURN and ERRORS_ARE_FATAL can be assigned to and retrieved from communicators using methods Comm.Set_errhandler and Comm.Get_errhandler, and similarly for windows and files. New custom error handlers can be created with Comm.Create_errhandler. like, you can literally make your own error handler. main character energy. ๐
When the predefined error handler ERRORS_RETURN is set, errors returned from MPI calls within Python code will raise an instance of the exception class Exception, which is a subclass of the standard Python exception RuntimeError. so it comes back as a whole exception, not just silently vibing.
Note: After import, mpi4py overrides the default MPI rules governing inheritance of error handlers. TheERRORS_RETURNerror handler is set in the predefinedCOMM_SELFandCOMM_WORLDcommunicators, as well as any newComm,Win, orFileinstance created through mpi4py. If you ever pass such handles to C/C++/Fortran library code, it is recommended to set theERRORS_ARE_FATALerror handler on them to ensure MPI errors do not pass silently. ๐ซถ so like, if you're handing your handles off to the C besties, switch to fatal so nothing gets swept under the rug, no cap.
Warning: Importing withfrom mpi4py.MPI import *will cause a name clashing with the standard PythonExceptionbase class. so likeโฆ don't do that unless you want chaos. ๐๐
๐ TUTORIAL ๐
Warning: Under construction. Contributions very welcome! ๐ง bestie it's a work in progress, come help us build it.
Tip: Rolf Rabenseifner at HLRS developed a comprehensive MPI-3.1/4.0 course with slides and a large set of exercises including solutions. This material is available online for self-study. The slides and exercises show the C, Fortran, and Python (mpi4py) interfaces. For performance reasons, most Python exercises use NumPy arrays and communication routines involving buffer-like objects. go off king, the exercises are so good. ๐โจ
Tip: Victor Eijkhout at TACC authored the book Parallel Programming for Science and Engineering. This book is available online in PDF and HTML formats. The book covers parallel programming with MPI and OpenMP in C/C++ and Fortran, and MPI in Python using mpi4py. the way this book covers literally everything?? obsessed. ๐ฆ
MPI for Python supports convenient, pickle-based communication of generic Python object as well as fast, near C-speed, direct array data communication of buffer-provider objects (e.g., NumPy arrays). like, both the cozy option AND the fast option. bestie you get to pick your vibe. ๐
- Communication of generic Python objects
You have to use methods with all-lowercase names, like Comm.send, Comm.recv, Comm.bcast, Comm.scatter, Comm.gather. An object to be sent is passed as a parameter to the communication call, and the received object is simply the return value. lowercase = the pickle-y object vibe, got it. ๐
The Comm.isend and Comm.irecv methods return Request instances; completion of these methods can be managed using the Request.test and Request.wait methods. non-blocking girlies rise. ๐ง
The Comm.recv and Comm.irecv methods may be passed a buffer object that can be repeatedly used to receive messages avoiding internal memory allocation. This buffer must be sufficiently large to accommodate the transmitted messages; hence, any buffer passed to Comm.recv or Comm.irecv must be at least as long as the pickled data transmitted to the receiver. so like, size your buffer right or it's gonna be a whole mess. ๐ญ
Collective calls like Comm.scatter, Comm.gather, Comm.allgather, Comm.alltoall expect a single value or a sequence of Comm.size elements at the root or all process. They return a single value, a list of Comm.size elements, or None. yes bestie, sometimes she just returns None. that's the whole vibe. ๐
Note: MPI for Python uses the highest protocol version available in the Python runtime (see theHIGHEST_PROTOCOLconstant in thepicklemodule). The default protocol can be changed at import time by setting theMPI4PY_PICKLE_PROTOCOLenvironment variable, or at runtime by assigning a different value to thePROTOCOLattribute of thepickleobject within theMPImodule. so you got two levers to pull โ one at import, one at runtime. pick your fighter. ๐
- Communication of buffer-like objects
You have to use method names starting with an upper-case letter, like Comm.Send, Comm.Recv, Comm.Bcast, Comm.Scatter, Comm.Gather. capital letters = the fast buffer vibe. slay. ๐ฅ
In general, buffer arguments to these calls must be explicitly specified by using a 2/3-list/tuple like [data, MPI.DOUBLE], or [data, count, MPI.DOUBLE] (the former one uses the byte-size of data and the extent of the MPI datatype to define count). okay so 2-element or 3-element, and the short one does the count math for you. cute.
For vector collectives communication operations like Comm.Scatterv and Comm.Gatherv, buffer arguments are specified as [data, count, displ, datatype], where count and displ are sequences of integral values. four things, count and displ are sequences of ints. no cap. ๐ซถ
Automatic MPI datatype discovery for NumPy/GPU arrays and PEP-3118 buffers is supported, but limited to basic C types (all C/C99-native signed/unsigned integral types and single/double precision real/complex floating types) and availability of matching datatypes in the underlying MPI implementation. In this case, the buffer-provider object can be passed directly as a buffer argument, the count and MPI datatype will be inferred. so she sniffs out the type for you, but only for the basics, and only if your MPI implementation actually has a matching datatype. ๐ฆ
If mpi4py is built against a GPU-aware MPI implementation, GPU arrays can be passed to upper-case methods as long as they have either the __dlpack__ and __dlpack_device__ methods or the __cuda_array_interface__ attribute that are compliant with the respective standard specifications. Moreover, only C-contiguous or Fortran-contiguous GPU arrays are supported. It is important to note that GPU buffers must be fully ready before any MPI routines operate on them to avoid race conditions. This can be ensured by using the synchronization API of your array library. mpi4py does not have access to any GPU-specific functionality and thus cannot perform this operation automatically for users. ๐ so like, YOU gotta sync your GPU buffers before MPI touches them, mpi4py literally cannot do it for you. do not skip this step bestie, race conditions are not the vibe.
๐ Running Python scripts with MPI ๐
Most MPI programs can be run with the command mpiexec. In practice, running Python programs looks like:
$ mpiexec -n 4 python script.py
to run the program with 4 processors. four little workers, one little script. ๐ซถ
๐ Point-to-Point Communication ๐
- Python objects (pickle under the hood):
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
if rank == 0:
data = {'a': 7, 'b': 3.14}
comm.send(data, dest=1, tag=11)
elif rank == 1:
data = comm.recv(source=0, tag=11)
- Python objects with non-blocking communication:
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
if rank == 0:
data = {'a': 7, 'b': 3.14}
req = comm.isend(data, dest=1, tag=11)
req.wait()
elif rank == 1:
req = comm.irecv(source=0, tag=11)
data = req.wait()
- NumPy arrays (the fast way!): โจ
okay bestie we are STILL in point-to-point territory and the glow-up is real โ mpi4py will either hold your datatype's hand or just read your mind and figure it out itself. pick your fighter ๐
from mpi4py import MPI
import numpy
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
# passing MPI datatypes explicitly
if rank == 0:
data = numpy.arange(1000, dtype='i')
comm.Send([data, MPI.INT], dest=1, tag=77)
elif rank == 1:
data = numpy.empty(1000, dtype='i')
comm.Recv([data, MPI.INT], source=0, tag=77)
# automatic MPI datatype discovery
if rank == 0:
data = numpy.arange(100, dtype=numpy.float64)
comm.Send(data, dest=1, tag=13)
elif rank == 1:
data = numpy.empty(100, dtype=numpy.float64)
comm.Recv(data, source=0, tag=13)
ngl the second half is mpi4py doing automatic MPI datatype discovery โ you hand it the buffer and it just knows. no cap. ๐ฅ
๐ซถ Collective Communication ๐ซถ
okay so point-to-point is giving "just us two" energy, but collective ops are the group chat โ everybody eats at the same time. let's gooo:
- Broadcasting a Python dictionary: rank 0 is holding the dict, and
comm.bcast(data, root=0)beams it to literally everyone. the other ranks just sit there withdata = Noneand wait for the serve. main character behavior fr fr.
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
if rank == 0:
data = {'key1' : [7, 2.72, 2+3j],
'key2' : ( 'abc', 'xyz')}
else:
data = None
data = comm.bcast(data, root=0)
- Scattering Python objects: root builds a whole list of squares
[(i+1)**2 for i in range(size)], thencomm.scatter(data, root=0)hands each rank its own lil slice, and theassertis there to make sure everybody got exactly what they were owed. vibe check passed โจ
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
if rank == 0:
data = [(i+1)**2 for i in range(size)]
else:
data = None
data = comm.scatter(data, root=0)
assert data == (rank+1)**2
- Gathering Python objects: the reverse serve ๐ซ โ every rank computes its own
(rank+1)**2and hands it over, root collects the whole list withcomm.gather(data, root=0), and the non-roots getNoneback. not me checking withassert data is None๐ญ
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
data = (rank+1)**2
data = comm.gather(data, root=0)
if rank == 0:
for i in range(size):
assert data[i] == (i+1)**2
else:
assert data is None
- Broadcasting a NumPy array: root has
np.arange(100, dtype='i'), everyone else pre-allocatesnp.empty(100, dtype='i'), thencomm.Bcast(data, root=0)fills it in. lowercasebcastreturns the object, uppercaseBcastfills your buffer โ the caps version is the buffer queen ๐
from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
if rank == 0:
data = np.arange(100, dtype='i')
else:
data = np.empty(100, dtype='i')
comm.Bcast(data, root=0)
for i in range(100):
assert data[i] == i
- Scattering NumPy arrays: root makes a big
[size, 100]sendbufand does the lilsendbuf.T[:,:] = range(size)trick so every row is a rank number. thencomm.Scatter(sendbuf, recvbuf, root=0)gives each rank its ownrecvbufof 100, andnp.allclose(recvbuf, rank)confirms it. obsessed with this one ๐
from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
sendbuf = None
if rank == 0:
sendbuf = np.empty([size, 100], dtype='i')
sendbuf.T[:,:] = range(size)
recvbuf = np.empty(100, dtype='i')
comm.Scatter(sendbuf, recvbuf, root=0)
assert np.allclose(recvbuf, rank)
- Gathering NumPy arrays: every rank fills a
sendbufof 100 withnp.zeros(100, dtype='i') + rank, root pre-allocates[size, 100]for therecvbuf, andcomm.Gather(sendbuf, recvbuf, root=0)stacks it all up. then root double-checks every row. it's giving meticulous ๐
from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
sendbuf = np.zeros(100, dtype='i') + rank
recvbuf = None
if rank == 0:
recvbuf = np.empty([size, 100], dtype='i')
comm.Gather(sendbuf, recvbuf, root=0)
if rank == 0:
for i in range(size):
assert np.allclose(recvbuf[i,:], i)
- Parallel matrix-vector product: the iconic
matvec(comm, A, x)function โm = A.shape[0]is your local row count,p = comm.Get_size()is how many of us there are,xg = numpy.zeros(m*p, dtype='d')is where the fullxgets rebuilt,comm.Allgather([x, MPI.DOUBLE], [xg, MPI.DOUBLE])does the sharing, and theny = numpy.dot(A, xg)is the actual math. the way thatAllgatherjust makes the whole vector appear everywhereโฆ ate. ๐ฅ
from mpi4py import MPI
import numpy
def matvec(comm, A, x):
m = A.shape[0] # local rows
p = comm.Get_size()
xg = numpy.zeros(m*p, dtype='d')
comm.Allgather([x, MPI.DOUBLE],
[xg, MPI.DOUBLE])
y = numpy.dot(A, xg)
return y
๐ Input/Output (MPI-IO) ๐
yes bestie, we're doing file I/O in parallel and honestly it's a whole vibe.
- Collective I/O with NumPy arrays: you set
amode = MPI.MODE_WRONLY|MPI.MODE_CREATE, open the file withMPI.File.Open(comm, "./datafile.contig", amode), fill a buffer of 10 ints with your rank, then computeoffset = comm.Get_rank()*buffer.nbytesso nobody's stepping on anyone's toes.fh.Write_at_all(offset, buffer)drops it in, thenfh.Close()closes it out. clean. periodt. ๐
from mpi4py import MPI
import numpy as np
amode = MPI.MODE_WRONLY|MPI.MODE_CREATE
comm = MPI.COMM_WORLD
fh = MPI.File.Open(comm, "./datafile.contig", amode)
buffer = np.empty(10, dtype=np.int)
buffer[:] = comm.Get_rank()
offset = comm.Get_rank()*buffer.nbytes
fh.Write_at_all(offset, buffer)
fh.Close()
- Non-contiguous Collective I/O with NumPy arrays and datatypes: the โจfancyโจ version.
item_count = 10, buffer full of your rank, thenfiletype = MPI.INT.Create_vector(item_count, 1, size)makes a custom datatype andfiletype.Commit()locks it in.displacement = MPI.INT.Get_size()*rankis where each rank starts,fh.Set_view(displacement, filetype=filetype)sets the view,fh.Write_all(buffer)writes it, and thenfiletype.Free()+fh.Close()clean everything up. iykyk ๐ฆ
from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
amode = MPI.MODE_WRONLY|MPI.MODE_CREATE
fh = MPI.File.Open(comm, "./datafile.noncontig", amode)
item_count = 10
buffer = np.empty(item_count, dtype='i')
buffer[:] = rank
filetype = MPI.INT.Create_vector(item_count, 1, size)
filetype.Commit()
displacement = MPI.INT.Get_size()*rank
fh.Set_view(displacement, filetype=filetype)
fh.Write_all(buffer)
filetype.Free()
fh.Close()
๐ง Dynamic Process Management ๐ง
this is the "we spawn our own friends" section and it's genuinely iconic.
- Compute Pi - Master (or parent, or client) side: you
MPI.COMM_SELF.Spawn(sys.executable, args=['cpi.py'], maxprocs=5)to boot up 5 lil workers, thencomm.Bcast([N, MPI.INT], root=MPI.ROOT)sendsN = numpy.array(100, 'i')out to them.comm.Reduce(None, [PI, MPI.DOUBLE], op=MPI.SUM, root=MPI.ROOT)collects the partial sums intoPI = numpy.array(0.0, 'd'),print(PI)shows the tea, andcomm.Disconnect()says bye. ๐
#!/usr/bin/env python
from mpi4py import MPI
import numpy
import sys
comm = MPI.COMM_SELF.Spawn(sys.executable,
args=['cpi.py'],
maxprocs=5)
N = numpy.array(100, 'i')
comm.Bcast([N, MPI.INT], root=MPI.ROOT)
PI = numpy.array(0.0, 'd')
comm.Reduce(None, [PI, MPI.DOUBLE],
op=MPI.SUM, root=MPI.ROOT)
print(PI)
comm.Disconnect()
- Compute Pi - Worker (or child, or server) side: the worker grabs its parent with
comm = MPI.Comm.Get_parent(), checkssizeandrank, receivesN = numpy.array(0, dtype='i')viacomm.Bcast([N, MPI.INT], root=0), then does the classich = 1.0 / N; s = 0.0Riemann-sum loop overrange(rank, N, size)computingx = h * (i + 0.5)ands += 4.0 / (1.0 + x**2). wraps it asPI = numpy.array(s * h, dtype='d'), sends it home withcomm.Reduce([PI, MPI.DOUBLE], None, op=MPI.SUM, root=0), and dips withcomm.Disconnect(). ๐ญ so proud of them
#!/usr/bin/env python
from mpi4py import MPI
import numpy
comm = MPI.Comm.Get_parent()
size = comm.Get_size()
rank = comm.Get_rank()
N = numpy.array(0, dtype='i')
comm.Bcast([N, MPI.INT], root=0)
h = 1.0 / N; s = 0.0
for i in range(rank, N, size):
x = h * (i + 0.5)
s += 4.0 / (1.0 + x**2)
PI = numpy.array(s * h, dtype='d')
comm.Reduce([PI, MPI.DOUBLE], None,
op=MPI.SUM, root=0)
comm.Disconnect()
โญ GPU-aware MPI + Python GPU arrays โญ
yes we're on the GPU now, put your seatbelt on bestie ๐
- Reduce-to-all CuPy arrays: import
cupy as cp, makesendbuf = cp.arange(10, dtype='i')andrecvbuf = cp.empty_like(sendbuf), then synchronize the stream withcp.cuda.get_current_stream().synchronize()before you do anything โ do not skip this, the sync is the whole point.comm.Allreduce(sendbuf, recvbuf)runs the reduce-to-all, andassert cp.allclose(recvbuf, sendbuf*size)confirms everyone's numbers added up right. ๐ฅ
from mpi4py import MPI
import cupy as cp
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
sendbuf = cp.arange(10, dtype='i')
recvbuf = cp.empty_like(sendbuf)
cp.cuda.get_current_stream().synchronize()
comm.Allreduce(sendbuf, recvbuf)
assert cp.allclose(recvbuf, sendbuf*size)
๐ One-Sided Communication (RMA) ๐
one-sided = you don't need the other guy to be "listening" in a matching call. it's giving independent woman energy ๐
- Read from (write to) the entire RMA window: set
datatype = MPI.FLOAT, grabnp_dtype = dtlib.to_numpy_dtype(datatype)anditemsize = datatype.Get_size(). withN = 10, only rank 0 allocates the window:win_size = N * itemsize if rank == 0 else 0, thenwin = MPI.Win.Allocate(win_size, comm=comm). rank 0 fillsbufwith42,win.Lock(rank=0),win.Put(buf, target_rank=0),win.Unlock(rank=0), thencomm.Barrier(). everybody else hits thecomm.Barrier()first, then locks,win.Get(buf, target_rank=0), unlocks, andassert np.all(buf == 42). beautiful. no notes. ๐ฆ
import numpy as np
from mpi4py import MPI
from mpi4py.util import dtlib
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
datatype = MPI.FLOAT
np_dtype = dtlib.to_numpy_dtype(datatype)
itemsize = datatype.Get_size()
N = 10
win_size = N * itemsize if rank == 0 else 0
win = MPI.Win.Allocate(win_size, comm=comm)
buf = np.empty(N, dtype=np_dtype)
if rank == 0:
buf.fill(42)
win.Lock(rank=0)
win.Put(buf, target_rank=0)
win.Unlock(rank=0)
comm.Barrier()
else:
comm.Barrier()
win.Lock(rank=0)
win.Get(buf, target_rank=0)
win.Unlock(rank=0)
assert np.all(buf == 42)
- Accessing a part of the RMA window using the target argument, which is defined as
(offset, count, datatype)โ this is the "I only want a slice of the window" move. hereN = comm.Get_size() + 1, and the window gets allocated withsize=win_size,disp_unit=itemsize,comm=comm. rank 0 reaches in withmem = np.frombuffer(win, dtype=np_dtype)and fills it withmem[:] = np.arange(len(mem), dtype=np_dtype), thencomm.Barrier(). everybody setsbuf = np.zeros(3, dtype=np_dtype)andtarget = (rank, 2, datatype)โ that's offset, count, datatype โ then lock /win.Get(buf, target_rank=0, target=target)/ unlock, andassert np.all(buf == [rank, rank+1, 0]). the0at the end is the untouched window cell. chef's kiss ๐
import numpy as np
from mpi4py import MPI
from mpi4py.util import dtlib
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
datatype = MPI.FLOAT
np_dtype = dtlib.to_numpy_dtype(datatype)
itemsize = datatype.Get_size()
N = comm.Get_size() + 1
win_size = N * itemsize if rank == 0 else 0
win = MPI.Win.Allocate(
size=win_size,
disp_unit=itemsize,
comm=comm,
)
if rank == 0:
mem = np.frombuffer(win, dtype=np_dtype)
mem[:] = np.arange(len(mem), dtype=np_dtype)
comm.Barrier()
buf = np.zeros(3, dtype=np_dtype)
target = (rank, 2, datatype)
win.Lock(rank=0)
win.Get(buf, target_rank=0, target=target)
win.Unlock(rank=0)
assert np.all(buf == [rank, rank+1, 0])
๐ธ Wrapping with SWIG ๐ธ
you can wrap your own C code and let Python call it. it's giving "i made this" ๐ซถ
- C source:
/* file: helloworld.c */
void sayhello(MPI_Comm comm)
{
int size, rank;
MPI_Comm_size(comm, &size);
MPI_Comm_rank(comm, &rank);
printf("Hello, World! "
"I am process %d of %d.\n",
rank, size);
}
- SWIG interface file:
// file: helloworld.i
%module helloworld
%{
#include <mpi.h>
#include "helloworld.c"
}%
%include mpi4py/mpi4py.i
%mpi4py_typemap(Comm, MPI_Comm);
void sayhello(MPI_Comm comm);
- Try it in the Python prompt:
>>> from mpi4py import MPI
>>> import helloworld
>>> helloworld.sayhello(MPI.COMM_WORLD)
Hello, World! I am process 0 of 1.
๐ Wrapping with F2Py ๐
same energy but Fortran. bestie we contain multitudes โจ
- Fortran 90 source:
! file: helloworld.f90
subroutine sayhello(comm)
use mpi
implicit none
integer :: comm, rank, size, ierr
call MPI_Comm_size(comm, size, ierr)
call MPI_Comm_rank(comm, rank, ierr)
print *, 'Hello, World! I am process ',rank,' of ',size,'.'
end subroutine sayhello
- Compiling example using f2py:
$ f2py -c --f90exec=mpif90 helloworld.f90 -m helloworld
- Try it in the Python prompt: notice the
MPI.COMM_WORLD.py2f()move โ that's you converting the Python communicator into the Fortran handle the wrapped code expects ๐
>>> from mpi4py import MPI
>>> import helloworld
>>> fcomm = MPI.COMM_WORLD.py2f()
>>> helloworld.sayhello(fcomm)
Hello, World! I am process 0 of 1.
๐ MPI4PY ๐
The MPI for Python package.
okay so real talk, what even is this. let me put you on:
The Message Passing Interface (MPI) is a standardized and portable message-passing system designed to function on a wide variety of parallel computers. The MPI standard defines the syntax and semantics of library routines and allows users to write portable programs in the main scientific programming languages (Fortran, C, or C++). Since its release, the MPI specification has become the leading standard for message-passing libraries for parallel computers.
MPI for Python provides MPI bindings for the Python programming language, allowing any Python program to exploit multiple processors. This package build on the MPI specification and provides an object oriented interface which closely follows MPI-2 C++ bindings.
โ๏ธ Runtime configuration options โ๏ธ
mpi4py.rcโ This object has attributes exposing runtime configuration options that become effective at import time of theMPImodule.
tl;dr: you tweakmpi4py.rcbefore you importMPI, and that's when the settings actually kick in. timing is everything bestie ๐
๐ Attributes Summary ๐
okay bestie, here's the whole squad at a glance, no scrolling required ๐
initializeโ Automatic MPI initialization at import โจthreadsโ Request initialization with thread support ๐งตthread_levelโ Level of thread support to requestfinalizeโ Automatic MPI finalization at exitfast_reduceโ Use tree-based reductions for objects ๐ณrecv_mprobeโ Use matched probes to receive objects ๐irecv_bufszโ Default buffer size in bytes forirecv()๐ฆerrorsโ Error handling policy ๐จ
๐ Attributes Documentation ๐
mpi4py.rc.initialize
Automatic MPI initialization at import.
- Type:
bool - Default:
True
See also: MPI4PY_RC_INITIALIZE
mpi4py.rc.threads
Request initialization with thread support.
- Type:
bool - Default:
True
See also: MPI4PY_RC_THREADS
mpi4py.rc.thread_level
Level of thread support to request.
- Type:
str - Default:
"multiple" - Choices:
"multiple","serialized","funneled","single"
See also: MPI4PY_RC_THREAD_LEVEL
mpi4py.rc.finalize
Automatic MPI finalization at exit.
If set to None, the value of mpi4py.rc.initialize is used.
- Type:
Noneorbool - Default:
None
See also: MPI4PY_RC_FINALIZE
mpi4py.rc.fast_reduce
Use tree-based reductions for objects.
- Type:
bool - Default:
True
See also: MPI4PY_RC_FAST_REDUCE
mpi4py.rc.recv_mprobe
Use matched probes to receive objects.
- Type:
bool - Default:
True
See also: MPI4PY_RC_RECV_MPROBE
mpi4py.rc.irecv_bufsz
Default buffer size in bytes for irecv().
- Type:
int - Default:
32768
See also: MPI4PY_RC_IRECV_BUFSZ
Added in version 4.0.0.
mpi4py.rc.errors
Error handling policy.
- Type:
str - Default:
"exception" - Choices:
"exception","default","abort","fatal"
See also: MPI4PY_RC_ERRORS
โจ Example โจ
MPI for Python features automatic initialization and finalization of the MPI execution environment โ iconic behaviour, honestly ๐. But if you wanna be the main character and drive the wheel yourself, you can use the mpi4py.rc object to handle MPI initialization and finalization programmatically:
import mpi4py
mpi4py.rc.initialize = False # do not initialize MPI automatically
mpi4py.rc.finalize = False # do not finalize MPI automatically
from mpi4py import MPI # import the 'MPI' module
MPI.Init() # manual initialization of the MPI environment
... # your finest code here ...
MPI.Finalize() # manual finalization of the MPI environment
๐ Environment variables ๐
The following environment variables override the corresponding attributes of the mpi4py.rc and MPI.pickle objects at import time of the MPI module. fr fr, they get the final say ๐ซถ
Note: For variables of boolean type, accepted values are0and1(interpreted asFalseandTrue, respectively), and strings specifying a YAML boolean value (case-insensitive). Soy,yes,on,trueโฆ all of that counts, lowercase or not ๐
MPI4PY_RC_INITIALIZE
- Type:
bool - Default:
True
Whether to automatically initialize MPI at import time of the mpi4py.MPI module.
See also: mpi4py.rc.initialize
Added in version 4.0.0.
MPI4PY_RC_FINALIZE
- Type:
None|bool - Default:
None - Choices:
None,True,False
Whether to automatically finalize MPI at exit time of the Python process.
See also: mpi4py.rc.finalize
Added in version 4.0.0.
MPI4PY_RC_THREADS
- Type:
bool - Default:
True
Whether to initialize MPI with thread support.
See also: mpi4py.rc.threads
Added in version 3.1.0.
MPI4PY_RC_THREAD_LEVEL
- Default:
"multiple" - Choices:
"single","funneled","serialized","multiple"
The level of required thread support.
See also: mpi4py.rc.thread_level
Added in version 3.1.0.
MPI4PY_RC_FAST_REDUCE
- Type:
bool - Default:
True
Whether to use tree-based reductions for objects. ๐ณ
See also: mpi4py.rc.fast_reduce
Added in version 3.1.0.
MPI4PY_RC_RECV_MPROBE
- Type:
bool - Default:
True
Whether to use matched probes to receive objects.
See also: mpi4py.rc.recv_mprobe
MPI4PY_RC_IRECV_BUFSZ
- Type:
int - Default:
32768
Default buffer size in bytes for irecv().
See also: mpi4py.rc.irecv_bufsz
Added in version 4.0.0.
MPI4PY_RC_ERRORS
- Default:
"exception" - Choices:
"exception","default","abort","fatal"
Controls default MPI error handling policy.
See also: mpi4py.rc.errors
Added in version 3.1.0.
MPI4PY_PICKLE_PROTOCOL
- Type:
int - Default:
pickle.HIGHEST_PROTOCOL
Controls the default pickle protocol to use when communicating Python objects.
See also: PROTOCOL attribute of the MPI.pickle object within the MPI module.
Added in version 3.1.0.
MPI4PY_PICKLE_THRESHOLD
- Type:
int - Default:
262144
Controls the default buffer size threshold for switching from in-band to out-of-band buffer handling when using pickle protocol version 5 or higher.
See also: THRESHOLD attribute of the MPI.pickle object within the MPI module.
Added in version 3.1.2.
๐ Miscellaneous functions ๐
These are the lil' helper besties that don't fit anywhere else but still eat every time. ๐ซถ
mpi4py.profile(name, *, path=None)โ support for the MPI profiling interface, iykyk.
Parameters
- name (str) โ the name of the profiler library to load. Like, the actual thing you want loaded, bestie.
- path (sequence of str, optional) โ extra paths to go searching through for the profiler. Give it a whole list if you want.
Return type: None โ she gives you nothing back, she just does the thing. ๐
mpi4py.get_include()โ returns the directory inside the package that holds the header files. ๐
Extension modules that need to compile against mpi4py should use this function to locate the appropriate include directory. So like, if your extension is trying to link up with mpi4py, this is the function that hands you the address. Using Python distutils (or maybe NumPy distutils):
import mpi4py
Extension('extension_name', ...
include_dirs=[..., mpi4py.get_include()])
Return type: str โ a path string, bestie. โจ
mpi4py.get_config()โ returns a dictionary stuffed with info about MPI.
Changed in version 4.0.0: By default, this function returns an empty dictionary. No cap. But downstream packagers and distributors may alter such behavior โ so if yours isn't empty, that's them, not her.
To that end, MPI information must be provided under an mpi section within a UTF-8 encoded INI-style configuration file named mpi.cfg located at the top-level package directory. The configuration file is read and parsed using the configparser module. ๐
Return type: dict[str, str] โ keys are strings, values are strings, that's the whole vibe. ๐ธ
๐ MPI4PY.MPI ๐
Okay bestie, this is the main event. The MPI subpackage. Everything you actually came for lives down here. ๐
๐ Classes ๐
Ancillary
The supporting cast. They don't run the show but the show does not run without them. โจ
Datatypeโ Datatype object.Statusโ Status object.Requestโ Request handler.Prequestโ Persistent request handler.Grequestโ Generalized request handler.Opโ Reduction operation.Groupโ Group of processes.Infoโ Info object.Sessionโ Session context.
Communication
The talking-to-each-other girlies. This is where the whole "MPI" part actually happens. ๐ฃ๏ธ๐ฌ
Commโ Communication context.Intracommโ Intracommunicator.Topocommโ Topology intracommunicator.Cartcommโ Cartesian topology intracommunicator.Graphcommโ General graph topology intracommunicator.Distgraphcommโ Distributed graph topology intracommunicator.Intercommโ Intercommunicator.Messageโ Matched message.
One-sided operations
She does things to your memory without asking you for a turn first. Iconic behavior, honestly. ๐
Winโ Remote memory access context.
Input/Output
Reading and writing, but make it parallel. ๐
Fileโ File I/O context.
Error handling
For when things go sideways โ and bestie, sometimes they do. ๐ญ
Errhandlerโ Error handler.Exceptionโ Exception class.
Auxiliary
The lil' extras. The sprinkles on the cupcake. ๐ง
Pickleโ Pickle/unpickle Python objects.bufferโ Buffer.
๐ Functions ๐
Version inquiry
Asking the library who she is and where she came from. Main character energy fr fr. ๐
Get_version()โ Obtain the version number of the MPI standard.Get_library_version()โ Obtain the version string of the MPI library.
๐โญ๐
โจ Initialization and finalization โจ
Okay bestie, this is the get the party started section, and also the okay everybody go home section. Every MPI program has a whole lifecycle and these are the functions that run it. ๐
Init()โ Initialize the MPI execution environment. This is the "lights on, everyone in the group chat" moment.Init_thread([required])โ Initialize the MPI execution environment. Same energy asInit(), but you get to ask for a level of thread support viarequired.Finalize()โ Terminate the MPI execution environment. The "okay goodnight, love you, bye" of the whole program.Is_initialized()โ Indicate whetherInit()has been called.Is_finalized()โ Indicate whetherFinalize()has completed.Query_thread()โ Return the level of thread support provided by the MPI library.Is_thread_main()โ Indicate whether this thread calledInit()orInit_thread(). Like, are you the one who started all this? ๐
๐ Memory allocation ๐
For when you need memory that MPI itself is gonna care about โ message passing and remote memory access want their own special little space, not just whatever random buffer you had lying around. ๐ซถ
Alloc_mem(size[, info])โ Allocate memory for message passing and remote memory access.Free_mem(mem)โ Free memory allocated withAlloc_mem(). And yes, you have to use this one to free it โ the matching energy is the whole point. ๐
๐ธ Address manipulation ๐ธ
Memory addresses, but make it arithmetic you're not allowed to do by hand. MPI wants you to use its own helpers here because pointer math on these things is not a "just wing it" situation. ๐
Get_address(location)โ Get the address of a location in memory.Aint_add(base, disp)โ Return the sum of base address and displacement.Aint_diff(addr1, addr2)โ Return the difference between absolute addresses.
โฐ Timer โฐ
It's giving how long did that even take. Two functions, both absolute icons, both here so you can measure your own stuff instead of trusting time.time() on a cluster where the clocks are lowkey not your friend. ๐ฆ
Wtick()โ Return the resolution ofWtime().Wtime()โ Return an elapsed time on the calling processor.
๐ Error handling ๐
This whole section is the what went wrong and why department. Error codes, error classes, error strings โ it's a whole little ecosystem and ngl, most of the time you'll just read the string and move on. But if you're building something fancy, all of these are here for you. ๐ฅ
Get_error_class(errorcode)โ Convert an error code into an error class.Get_error_string(errorcode)โ Return the error string for a given error class or error code. Yes, it takes either one. It's flexible like that. โจAdd_error_class()โ Add an error class to the known error classes.Add_error_code(errorclass)โ Add an error code to an error class.Add_error_string(errorcode, string)โ Associate an error string with an error class or error code.Remove_error_class(errorclass)โ Remove an error class from the known error classes.Remove_error_code(errorcode)โ Remove an error code from the known error codes.Remove_error_string(errorcode)โ Remove error string association from error class or error code.
Okay so like โ add/remove pairs are a thing here. If you add a class, a code, or a string, there's a matching remove waiting for it. Keep track of what you registered bestie, because nobody else is gonna do it for you. ๐
๐ซ Dynamic process management ๐ซ
okay bestie, this is the whole "who even are my processes and how do we find each other" corner of the library. it's giving matchmaker energy fr fr ๐ซถ
Open_port([info])โ hands you back an address you can use to connect a whole lil group of processes together. the info is optional, no pressure ๐Close_port(port_name)โ shut that port down. bye bye ๐Publish_name(service_name, port_name[, info])โ put a service name out into the world so other folks can find it. info is optional here too โจUnpublish_name(service_name, port_name[, info])โ take that published service name back down. info optional, as always ๐Lookup_name(service_name[, info])โ got a service name and need the port name? this is the one that finds it for you. info optional, iykyk ๐
๐ง Miscellanea ๐ง
the grab-bag section!! random but iconic. every single one of these is a real one, no cap ๐
Attach_buffer(buf)โ attach a buffer that you provided, for sending stuff in buffered mode. it's giving "i brought my own bag" ๐Detach_buffer()โ rip out a buffer that was already attached. no args, just vibes ๐Flush_buffer()โ block right there until every single buffered message has actually been transmitted. patience, queen ๐Iflush_buffer()โ the nonblocking version of that flush, for your buffered messages. main character energy, doesn't wait around ๐ฅCompute_dims(nnodes, dims)โ returns a balanced distribution of processes per coordinate direction. math but make it fair โ๏ธGet_processor_name()โ gets you the name of the processor that's calling. literally just a name tag ๐ท๏ธRegister_datarep(datarep, read_fn, write_fn, ...)โ register user-defined data representations. yes bestie, you bring the read_fn, the write_fn, and the rest โจPcontrol(level)โ controls profiling. that's it, that's the whole job ๐
โญ Utilities โญ
get_vendor()โ info about the underlying MPI implementation. like a little "who made this" card for your MPI ๐
Attributes โจ
okay so this is the little constants shelf of mpi4py.MPI โ all the magic values that the library hands you so you never have to hardcode a weird number yourself ๐
every single one of them lives right here on the module, and here's the whole roster, no skips, no cuts, fr fr:
UNDEFINEDโ ConstantUNDEFINEDof typeint. ๐ซถANY_SOURCEโ ConstantANY_SOURCEof typeint.ANY_TAGโ ConstantANY_TAGof typeint.PROC_NULLโ ConstantPROC_NULLof typeint.ROOTโ ConstantROOTof typeint.BOTTOMโ ObjectBOTTOMof typeBottomType. not an int bestie, it's got its own whole type ๐IN_PLACEโ ObjectIN_PLACEof typeInPlaceType. again, its own type, iconic โจBUFFER_AUTOMATICโ ObjectBUFFER_AUTOMATICof typeBufferAutomaticType. yep, another one with a dedicated type ๐KEYVAL_INVALIDโ ConstantKEYVAL_INVALIDof typeint.TAG_UBโ ConstantTAG_UBof typeint.IOโ ConstantIOof typeint.WTIME_IS_GLOBALโ ConstantWTIME_IS_GLOBALof typeint.UNIVERSE_SIZEโ ConstantUNIVERSE_SIZEof typeint.APPNUMโ ConstantAPPNUMof typeint.LASTUSEDCODEโ ConstantLASTUSEDCODEof typeint.WIN_BASEโ ConstantWIN_BASEof typeint.WIN_SIZEโ ConstantWIN_SIZEof typeint.WIN_DISP_UNITโ ConstantWIN_DISP_UNITof typeint.WIN_CREATE_FLAVORโ ConstantWIN_CREATE_FLAVORof typeint.WIN_FLAVORโ ConstantWIN_FLAVORof typeint.WIN_MODELโ ConstantWIN_MODELof typeint.SUCCESSโ ConstantSUCCESSof typeint.ERR_LASTCODEโ ConstantERR_LASTCODEof typeint.ERR_COMMโ ConstantERR_COMMof typeint.
like, that's a lot of constants, and the vibe check says: most of them are just plain old int, a few of them got their own fancy type because they're built different ๐ฆ lowkey obsessed with how BOTTOM, IN_PLACE and BUFFER_AUTOMATIC refused to be basic ๐
ERR_COMMโ ConstantERR_COMM, of typeint(https://docs.python.org/3/library/functions.html#int). Another icon on the error-constant roster ๐ERR_GROUPโ ConstantERR_GROUP, of typeint(https://docs.python.org/3/library/functions.html#int). Yes bestie, it's anintagain. They all are. Sit with it ๐ซถERR_TYPEโ ConstantERR_TYPE, of typeint(https://docs.python.org/3/library/functions.html#int). โจERR_REQUESTโ ConstantERR_REQUEST, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ฅERR_OPโ ConstantERR_OP, of typeint(https://docs.python.org/3/library/functions.html#int). Short name, bigintenergy.ERR_ERRHANDLERโ ConstantERR_ERRHANDLER, of typeint(https://docs.python.org/3/library/functions.html#int). Say that name three times fast, I dare you ๐ญERR_BUFFERโ ConstantERR_BUFFER, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ERR_COUNTโ ConstantERR_COUNT, of typeint(https://docs.python.org/3/library/functions.html#int). Lowkey obsessed with how consistent this list is.ERR_TAGโ ConstantERR_TAG, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ERR_RANKโ ConstantERR_RANK, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ธERR_ROOTโ ConstantERR_ROOT, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ERR_TRUNCATEโ ConstantERR_TRUNCATE, of typeint(https://docs.python.org/3/library/functions.html#int). No cap.ERR_IN_STATUSโ ConstantERR_IN_STATUS, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ฆERR_PENDINGโ ConstantERR_PENDING, of typeint(https://docs.python.org/3/library/functions.html#int). Not me refreshing for this one to show up ๐ERR_TOPOLOGYโ ConstantERR_TOPOLOGY, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ERR_DIMSโ ConstantERR_DIMS, of typeint(https://docs.python.org/3/library/functions.html#int). โญERR_ARGโ ConstantERR_ARG, of typeint(https://docs.python.org/3/library/functions.html#int). Tiny name, still anint.ERR_OTHERโ ConstantERR_OTHER, of typeint(https://docs.python.org/3/library/functions.html#int). The main character of "miscellaneous" ๐ซถERR_UNKNOWNโ ConstantERR_UNKNOWN, of typeint(https://docs.python.org/3/library/functions.html#int). The way that even the unknown one is a knownintโฆ iconic.ERR_INTERNโ ConstantERR_INTERN, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ERR_INFOโ ConstantERR_INFO, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ERR_FILEโ ConstantERR_FILE, of typeint(https://docs.python.org/3/library/functions.html#int). โจERR_WINโ ConstantERR_WIN, of typeint(https://docs.python.org/3/library/functions.html#int). Literally a win ๐ERR_KEYVALโ ConstantERR_KEYVAL, of typeint(https://docs.python.org/3/library/functions.html#int). And we're still going, bestie ๐งERR_INFO_KEY<#mpi4py.MPI.ERR_INFO_KEY> โ a constant, bestie, and its whole vibe isint๐ (peephttps://docs.python.org/3/library/functions.html#intif you need the int lore).ERR_INFO_VALUE<#mpi4py.MPI.ERR_INFO_VALUE> โ another constant, also givingintenergy โจ (samehttps://docs.python.org/3/library/functions.html#int).ERR_INFO_NOKEY<#mpi4py.MPI.ERR_INFO_NOKEY> โ constant, typeint, no notes ๐ (https://docs.python.org/3/library/functions.html#int).ERR_ACCESS<#mpi4py.MPI.ERR_ACCESS> โ constant, and yes it's anint๐ฆ (https://docs.python.org/3/library/functions.html#int).ERR_AMODE<#mpi4py.MPI.ERR_AMODE> โ constant of typeint, that's the whole post ๐ธ (https://docs.python.org/3/library/functions.html#int).ERR_BAD_FILE<#mpi4py.MPI.ERR_BAD_FILE> โ constant,intcoded ๐ (https://docs.python.org/3/library/functions.html#int).ERR_FILE_EXISTS<#mpi4py.MPI.ERR_FILE_EXISTS> โ constant, typeint, lowkey iconic ๐ญ (https://docs.python.org/3/library/functions.html#int).ERR_FILE_IN_USE<#mpi4py.MPI.ERR_FILE_IN_USE> โ constant, typeint, slay ๐ฅ (https://docs.python.org/3/library/functions.html#int).ERR_NO_SPACE<#mpi4py.MPI.ERR_NO_SPACE> โ constant of typeint๐ (https://docs.python.org/3/library/functions.html#int).ERR_NO_SUCH_FILE<#mpi4py.MPI.ERR_NO_SUCH_FILE> โ constant,int, periodt ๐ (https://docs.python.org/3/library/functions.html#int).ERR_IO<#mpi4py.MPI.ERR_IO> โ constant, typeint๐ซถ (https://docs.python.org/3/library/functions.html#int).ERR_READ_ONLY<#mpi4py.MPI.ERR_READ_ONLY> โ constant, and yeah,int๐ (https://docs.python.org/3/library/functions.html#int).ERR_CONVERSION<#mpi4py.MPI.ERR_CONVERSION> โ constant of typeintโญ (https://docs.python.org/3/library/functions.html#int).ERR_DUP_DATAREP<#mpi4py.MPI.ERR_DUP_DATAREP> โ constant,int, fr fr ๐ (https://docs.python.org/3/library/functions.html#int).ERR_UNSUPPORTED_DATAREP<#mpi4py.MPI.ERR_UNSUPPORTED_DATAREP> โ constant of typeint๐ (https://docs.python.org/3/library/functions.html#int).ERR_UNSUPPORTED_OPERATION<#mpi4py.MPI.ERR_UNSUPPORTED_OPERATION> โ constant,int, we move ๐ง (https://docs.python.org/3/library/functions.html#int).ERR_NAME<#mpi4py.MPI.ERR_NAME> โ constant, typeint๐ (https://docs.python.org/3/library/functions.html#int).ERR_NO_MEM<#mpi4py.MPI.ERR_NO_MEM> โ constant,intenergy only โจ (https://docs.python.org/3/library/functions.html#int).ERR_NOT_SAME<#mpi4py.MPI.ERR_NOT_SAME> โ constant of typeint๐ (https://docs.python.org/3/library/functions.html#int).ERR_PORT<#mpi4py.MPI.ERR_PORT> โ constant, typeint, no cap ๐ธ (https://docs.python.org/3/library/functions.html#int).ERR_QUOTA<#mpi4py.MPI.ERR_QUOTA> โ constant,int, ate ๐ (https://docs.python.org/3/library/functions.html#int).ERR_SERVICE<#mpi4py.MPI.ERR_SERVICE> โ constant of typeint๐ฆ (https://docs.python.org/3/library/functions.html#int).ERR_SPAWN<#mpi4py.MPI.ERR_SPAWN> โ constant of typeint๐ฅ (https://docs.python.org/3/library/functions.html#int).
okay bestie, the constant parade continues ๐
and real talk? every single one of these is an int โ yes, that int, the Python built-in, the one whose docs live over at docs.python.org/3/library/functions.html#int. So I'm saying it once up here, and then we're just gonna vibe through the list together. no skipping, no "you get the idea", we list all of them. periodt. ๐
ERR_SPAWNโ a constant, and its type isint.ERR_BASEโ constant, typeint, living its best life.ERR_SIZEโ yep, another constant, and yes, it's anint.ERR_DISPโ constant. type:int. moving on ๐ฆERR_ASSERTโ constant of typeint, no cap.ERR_LOCKTYPEโ constant,int, iconic.ERR_RMA_CONFLICTโ constant, typeint.ERR_RMA_SYNCโ constant, typeint.ERR_RMA_RANGEโ constant, typeint.ERR_RMA_ATTACHโ constant, typeint.ERR_RMA_SHAREDโ constant, typeint.ERR_RMA_FLAVORโ constant, typeint.ORDER_Cโ a constant, and it's anint.ORDER_Fโ constant, typeint.ORDER_FORTRANโ constant, typeint.TYPECLASS_INTEGERโ constant, typeint.TYPECLASS_REALโ constant, typeint.TYPECLASS_COMPLEXโ constant, typeint.DISTRIBUTE_NONEโ constant, typeint.DISTRIBUTE_BLOCKโ constant, typeint.DISTRIBUTE_CYCLICโ constant, typeint.DISTRIBUTE_DFLT_DARGโ constant, typeint.COMBINER_NAMEDโ constant, typeint.COMBINER_DUPโ constant, typeint.
and the list keeps going, bestie, we're not done yet โ the next chunk is right behind this one ๐ซถ
COMBINER_DUPโ ConstantCOMBINER_DUPof typeint(that's thehttps://docs.python.org/3/library/functions.html#intone ๐ ), anchored at#mpi4py.MPI.COMBINER_DUP.COMBINER_CONTIGUOUSโ ConstantCOMBINER_CONTIGUOUSof typeint(https://docs.python.org/3/library/functions.html#int), living at#mpi4py.MPI.COMBINER_CONTIGUOUS.COMBINER_VECTORโ ConstantCOMBINER_VECTORof typeint(https://docs.python.org/3/library/functions.html#int), bestie it's at#mpi4py.MPI.COMBINER_VECTOR.COMBINER_HVECTORโ ConstantCOMBINER_HVECTORof typeint(https://docs.python.org/3/library/functions.html#int), chillin' at#mpi4py.MPI.COMBINER_HVECTOR.COMBINER_INDEXEDโ ConstantCOMBINER_INDEXEDof typeint(https://docs.python.org/3/library/functions.html#int), anchored at#mpi4py.MPI.COMBINER_INDEXED.COMBINER_HINDEXEDโ ConstantCOMBINER_HINDEXEDof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_HINDEXED.COMBINER_INDEXED_BLOCKโ ConstantCOMBINER_INDEXED_BLOCKof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_INDEXED_BLOCK.COMBINER_HINDEXED_BLOCKโ ConstantCOMBINER_HINDEXED_BLOCKof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_HINDEXED_BLOCK.COMBINER_STRUCTโ ConstantCOMBINER_STRUCTof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_STRUCT.COMBINER_SUBARRAYโ ConstantCOMBINER_SUBARRAYof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_SUBARRAY.COMBINER_DARRAYโ ConstantCOMBINER_DARRAYof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_DARRAY.COMBINER_RESIZEDโ ConstantCOMBINER_RESIZEDof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_RESIZED.COMBINER_VALUE_INDEXโ ConstantCOMBINER_VALUE_INDEXof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_VALUE_INDEX.COMBINER_F90_REALโ ConstantCOMBINER_F90_REALof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_F90_REAL.COMBINER_F90_COMPLEXโ ConstantCOMBINER_F90_COMPLEXof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_F90_COMPLEX.COMBINER_F90_INTEGERโ ConstantCOMBINER_F90_INTEGERof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.COMBINER_F90_INTEGER.
okay pausing the COMBINER marathon for a sec, new vibe category unlocked โจ
IDENTโ ConstantIDENTof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.IDENT.CONGRUENTโ ConstantCONGRUENTof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.CONGRUENT.SIMILARโ ConstantSIMILARof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.SIMILAR.UNEQUALโ ConstantUNEQUALof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.UNEQUAL.CARTโ ConstantCARTof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.CART.GRAPHโ ConstantGRAPHof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.GRAPH.DIST_GRAPHโ ConstantDIST_GRAPHof typeint(https://docs.python.org/3/library/functions.html#int), at#mpi4py.MPI.DIST_GRAPH.
okay continuing the constant lineup ๐
every single one of these is a constant of type int, and the Python docs link for int is literally the same every time, so here we go, one bullet per icon, nothing skipped, periodt โจ
UNWEIGHTEDโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.UNWEIGHTED. she's here, she's an int, she's unbothered ๐WEIGHTS_EMPTYโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.WEIGHTS_EMPTY. empty but make it iconic ๐COMM_TYPE_SHAREDโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.COMM_TYPE_SHARED. a whole comm type living her shared truth ๐ฆBSEND_OVERHEADโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.BSEND_OVERHEAD. the overhead girlie, we respect her โจWIN_FLAVOR_CREATEโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.WIN_FLAVOR_CREATE. flavor: create ๐WIN_FLAVOR_ALLOCATEโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.WIN_FLAVOR_ALLOCATE. flavor: allocate, and yes she's a different flavor, don't merge them bestie ๐WIN_FLAVOR_DYNAMICโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.WIN_FLAVOR_DYNAMIC. flavor: dynamic, main character energy ๐WIN_FLAVOR_SHAREDโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.WIN_FLAVOR_SHARED. flavor: shared, sharing is caring fr fr ๐WIN_SEPARATEโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.WIN_SEPARATE. separate, she needs her space ๐ธWIN_UNIFIEDโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.WIN_UNIFIED. unified, the way she brings everyone together ๐ญMODE_NOCHECKโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_NOCHECK. no check, no stress, lowkey the vibe ๐MODE_NOSTOREโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_NOSTORE. no store, not me storing anything today ๐ซถMODE_NOPUTโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_NOPUT. no put, and she means it โจMODE_NOPRECEDEโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_NOPRECEDE. no precede, she goes first or not at all ๐MODE_NOSUCCEEDโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_NOSUCCEED. no succeed, she's done after this, goodbye ๐LOCK_EXCLUSIVEโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.LOCK_EXCLUSIVE. exclusive lock, she does NOT share the aux ๐ฅLOCK_SHAREDโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.LOCK_SHARED. shared lock, actually she'll share the aux ๐MODE_RDONLYโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_RDONLY. read only, look but don't touch bestie ๐MODE_WRONLYโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_WRONLY. write only, she's typing, don't read over her shoulder ๐MODE_RDWRโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_RDWR. read and write, she does both, versatile queen ๐MODE_CREATEโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_CREATE. create mode, manifesting โจMODE_EXCLโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_EXCL. excl mode, if it exists already she's not doing it, no cap ๐ โโ๏ธMODE_DELETE_ON_CLOSEโ constant of typeint(https://docs.python.org/3/library/functions.html#int), anchor#mpi4py.MPI.MODE_DELETE_ON_CLOSE. delete on close, she leaves no trace, mysterious and iconic ๐
Like, more constants bestie, all of them int typed, all of them yours ๐ keep scrolling, the list does not stop:
MODE_DELETE_ON_CLOSEโ ConstantMODE_DELETE_ON_CLOSEof typeint. yes babe, another one ๐MODE_UNIQUE_OPENโ ConstantMODE_UNIQUE_OPENof typeint. โจMODE_SEQUENTIALโ ConstantMODE_SEQUENTIALof typeint. ๐ธMODE_APPENDโ ConstantMODE_APPENDof typeint. ๐SEEK_SETโ ConstantSEEK_SETof typeint. the classic trio begins ๐ฆSEEK_CURโ ConstantSEEK_CURof typeint. ๐SEEK_ENDโ ConstantSEEK_ENDof typeint. ๐DISPLACEMENT_CURRENTโ ConstantDISPLACEMENT_CURRENTof typeint. long name, tiny type ๐DISP_CURโ ConstantDISP_CURof typeint. its little nickname fr fr โจTHREAD_SINGLEโ ConstantTHREAD_SINGLEof typeint. threading era incoming ๐THREAD_FUNNELEDโ ConstantTHREAD_FUNNELEDof typeint. ๐งTHREAD_SERIALIZEDโ ConstantTHREAD_SERIALIZEDof typeint. ๐THREAD_MULTIPLEโ ConstantTHREAD_MULTIPLEof typeint. the most unhinged one, iconic ๐ฅVERSIONโ ConstantVERSIONof typeint. โญSUBVERSIONโ ConstantSUBVERSIONof typeint. โญMAX_PROCESSOR_NAMEโ ConstantMAX_PROCESSOR_NAMEof typeint. ๐ธMAX_ERROR_STRINGโ ConstantMAX_ERROR_STRINGof typeint. ๐ญMAX_PORT_NAMEโ ConstantMAX_PORT_NAMEof typeint. ๐ฆMAX_INFO_KEYโ ConstantMAX_INFO_KEYof typeint. ๐MAX_INFO_VALโ ConstantMAX_INFO_VALof typeint. ๐MAX_OBJECT_NAMEโ ConstantMAX_OBJECT_NAMEof typeint. ๐MAX_DATAREP_STRINGโ ConstantMAX_DATAREP_STRINGof typeint. say that three times fast, I dare you ๐MAX_LIBRARY_VERSION_STRINGโ ConstantMAX_LIBRARY_VERSION_STRINGof typeint. the longest name in the building and it ATE ๐
ngl bestie, every single one of these is just anintconstant. No cap. They live at<pink>mpi4py.MPI</pink>, and that's the whole vibe of this chunk ๐ซถ
โฆand the roster keeps going, bestie, because MPI has a datatype for everything ๐
here's the rest of the lineup, each one just vibing as an object of type Datatype:
DATATYPE_NULLโ ObjectDATATYPE_NULLof typeDatatype๐ซฅ (yes she's here, yes she's still aDatatype)PACKEDโ ObjectPACKEDof typeDatatype๐ฆBYTEโ ObjectBYTEof typeDatatype๐งฑAINTโ ObjectAINTof typeDatatypeโจOFFSETโ ObjectOFFSETof typeDatatype๐COUNTโ ObjectCOUNTof typeDatatype๐ขCHARโ ObjectCHARof typeDatatype๐คWCHARโ ObjectWCHARof typeDatatype๐ถSIGNED_CHARโ ObjectSIGNED_CHARof typeDatatypeโ๏ธSHORTโ ObjectSHORTof typeDatatype๐ฃINTโ ObjectINTof typeDatatype๐LONGโ ObjectLONGof typeDatatype๐LONG_LONGโ ObjectLONG_LONGof typeDatatype๐๐UNSIGNED_CHARโ ObjectUNSIGNED_CHARof typeDatatype๐UNSIGNED_SHORTโ ObjectUNSIGNED_SHORTof typeDatatype๐UNSIGNEDโ ObjectUNSIGNEDof typeDatatype๐ธUNSIGNED_LONGโ ObjectUNSIGNED_LONGof typeDatatype๐ฆUNSIGNED_LONG_LONGโ ObjectUNSIGNED_LONG_LONGof typeDatatype๐ฆ๐ฆFLOATโ ObjectFLOATof typeDatatype๐DOUBLEโ ObjectDOUBLEof typeDatatype๐๐LONG_DOUBLEโ ObjectLONG_DOUBLEof typeDatatype๐๐๐C_BOOLโ ObjectC_BOOLof typeDatatypeโINT8_Tโ ObjectINT8_Tof typeDatatype๐INT16_Tโ ObjectINT16_Tof typeDatatype๐INT32_Tโ ObjectINT32_Tof typeDatatype๐INT64_Tโ ObjectINT64_Tof typeDatatype๐UINT8_Tโ ObjectUINT8_Tof typeDatatype๐
Okay bestie the datatype menu continues and it is long โ every one of these is an object of type Datatype, and honestly they're all giving "same energy, different name". Here's the rest of the lineup: ๐
UINT16_Tโ theUINT16_Tobject, and yep, it's of typeDatatype. โจUINT32_Tโ theUINT32_Tobject, typeDatatype. ๐UINT64_Tโ theUINT64_Tobject, typeDatatype. ๐ฆC_COMPLEXโ theC_COMPLEXobject, of typeDatatype. ๐C_FLOAT_COMPLEXโ theC_FLOAT_COMPLEXobject, of typeDatatype. ๐ธC_DOUBLE_COMPLEXโ theC_DOUBLE_COMPLEXobject, of typeDatatype. ๐C_LONG_DOUBLE_COMPLEXโ theC_LONG_DOUBLE_COMPLEXobject, of typeDatatype. โญCXX_BOOLโ theCXX_BOOLobject, of typeDatatype. ๐ฅCXX_FLOAT_COMPLEXโ theCXX_FLOAT_COMPLEXobject, of typeDatatype. ๐CXX_DOUBLE_COMPLEXโ theCXX_DOUBLE_COMPLEXobject, of typeDatatype. ๐CXX_LONG_DOUBLE_COMPLEXโ theCXX_LONG_DOUBLE_COMPLEXobject, of typeDatatype. ๐SHORT_INTโ theSHORT_INTobject, of typeDatatype. ๐INT_INTโ theINT_INTobject, of typeDatatype. ๐TWOINTโ theTWOINTobject, of typeDatatype. ๐งLONG_INTโ theLONG_INTobject, of typeDatatype. โจFLOAT_INTโ theFLOAT_INTobject, of typeDatatype. ๐DOUBLE_INTโ theDOUBLE_INTobject, of typeDatatype. ๐ซถLONG_DOUBLE_INTโ theLONG_DOUBLE_INTobject, of typeDatatype. ๐ธCHARACTERโ theCHARACTERobject, of typeDatatype. ๐LOGICALโ theLOGICALobject, of typeDatatype. ๐INTEGERโ theINTEGERobject, of typeDatatype. ๐ฆREALโ theREALobject, of typeDatatype. ๐DOUBLE_PRECISIONโ theDOUBLE_PRECISIONobject, of typeDatatype. โญCOMPLEXโ theCOMPLEXobject, of typeDatatype. ๐ฅDOUBLE_COMPLEXโ theDOUBLE_COMPLEXobject, of typeDatatype. ๐LOGICAL1โ theLOGICAL1object, of typeDatatype. ๐LOGICAL2โ theLOGICAL2object, of typeDatatype. ๐
Not me listing out the entire datatype alphabet like it's a stan list ๐ญ every single one of these is an object of type <code>Datatype</code> and that's the whole vibe, no cap.
LOGICAL4โ bestie, this is objectLOGICAL4, and it's aDatatype๐LOGICAL8โ objectLOGICAL8, typeDatatypeโจINTEGER1โ objectINTEGER1, and yup, it's aDatatype๐INTEGER2โ objectINTEGER2, typeDatatype๐ธINTEGER4โ objectINTEGER4, typeDatatype๐ฆINTEGER8โ objectINTEGER8, typeDatatype๐INTEGER16โ objectINTEGER16, typeDatatypeโญREAL2โ objectREAL2, typeDatatype๐REAL4โ objectREAL4, typeDatatypeโจREAL8โ objectREAL8, typeDatatype๐REAL16โ objectREAL16, typeDatatype๐งCOMPLEX4โ objectCOMPLEX4, typeDatatype๐COMPLEX8โ objectCOMPLEX8, typeDatatype๐ซถCOMPLEX16โ objectCOMPLEX16, typeDatatype๐ธCOMPLEX32โ objectCOMPLEX32, typeDatatype๐UNSIGNED_INTโ objectUNSIGNED_INT, typeDatatype๐ฅSIGNED_SHORTโ objectSIGNED_SHORT, typeDatatypeโญSIGNED_INTโ objectSIGNED_INT, typeDatatype๐SIGNED_LONGโ objectSIGNED_LONG, typeDatatype๐SIGNED_LONG_LONGโ objectSIGNED_LONG_LONG, typeDatatype๐ฆBOOLโ objectBOOL, typeDatatypeโจSINT8_Tโ objectSINT8_T, typeDatatype๐SINT16_Tโ objectSINT16_T, typeDatatype๐SINT32_Tโ objectSINT32_T, typeDatatype๐งSINT64_Tโ objectSINT64_T, typeDatatype๐F_BOOLโ objectF_BOOL, typeDatatype๐ซถF_INTโ objectF_INT, typeDatatype๐F_FLOATโ objectF_FLOAT, typeDatatype๐ฅ
and the constant drop continues, bestie, no cap ๐
F_DOUBLEโ ObjectF_DOUBLEof typeDatatype๐F_COMPLEXโ ObjectF_COMPLEXof typeDatatypeโจF_FLOAT_COMPLEXโ ObjectF_FLOAT_COMPLEXof typeDatatype๐ฆF_DOUBLE_COMPLEXโ ObjectF_DOUBLE_COMPLEXof typeDatatype๐ธREQUEST_NULLโ ObjectREQUEST_NULLof typeRequest๐MESSAGE_NULLโ ObjectMESSAGE_NULLof typeMessage๐ซถMESSAGE_NO_PROCโ ObjectMESSAGE_NO_PROCof typeMessage๐ญOP_NULLโ ObjectOP_NULLof typeOp๐ฅMAXโ ObjectMAXof typeOp๐MINโ ObjectMINof typeOp๐SUMโ ObjectSUMof typeOpโญPRODโ ObjectPRODof typeOp๐LANDโ ObjectLANDof typeOp๐BANDโ ObjectBANDof typeOp๐LORโ ObjectLORof typeOp๐งBORโ ObjectBORof typeOp๐LXORโ ObjectLXORof typeOp๐BXORโ ObjectBXORof typeOpโจMAXLOCโ ObjectMAXLOCof typeOp๐ฆMINLOCโ ObjectMINLOCof typeOp๐ธREPLACEโ ObjectREPLACEof typeOp๐NO_OPโ ObjectNO_OPof typeOp๐ซถGROUP_NULLโ ObjectGROUP_NULLof typeGroup๐ญGROUP_EMPTYโ ObjectGROUP_EMPTYof typeGroup๐ฅINFO_NULLโ ObjectINFO_NULLof typeInfo๐INFO_ENVโ ObjectINFO_ENVof typeInfo๐ERRHANDLER_NULLโ ObjectERRHANDLER_NULLof typeErrhandlerโญERRORS_RETURNโ ObjectERRORS_RETURNof typeErrhandler๐ERRORS_ARE_FATALโ ObjectERRORS_ARE_FATALof typeErrhandler๐COMM_NULLโ ObjectCOMM_NULLof typeComm๐COMM_SELFโ ObjectCOMM_SELFof typeIntracomm๐ง
โ COMM_WORLD โ Object COMM_WORLD of type โ โ <#mpi4py.MPI.COMM_WORLD> โ Intracomm <#mpi4py.MPI โ โ โ .Intracomm> โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ WIN_NULL <#mpi4py.MPI โ Object WIN_NULL of type โ โ .WIN_NULL> โ Win <#mpi4py.MPI.Win> โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ FILE_NULL <#mpi4py.MPI โ Object FILE_NULL of type โ โ .FILE_NULL> โ File <#mpi4py.MPI.File> โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ pickle <#mpi4py.MPI.pickle>โ Object pickle of type โ โ โ Pickle <#mpi4py.MPI โ โ โ .Pickle> โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โจ MPI4PY.TYPING โจ
Added in version 4.0.0. ๐
Okay so bestie, this module is the one that hands out type aliases <https://docs.python.org/3/glossary.html#term-type-alias> that get used to add type hints <https://docs.python.org/3/glossary.html#term-type-hint> onto all the various functions and methods living inside the MPI <#module-mpi4py.MPI> module. It's giving โจtype safety eraโจ and we are obsessed. ๐
See also:
- Module
typing<https://docs.python.org/3/library/typing.html#module-typing>- Documentation of the
typing<https://docs.python.org/3/library/typing.html#module-typing> standard module. ๐
- Documentation of the
๐ธ Types Summary ๐ธ
โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ SupportsBuffer โ Python buffer protocol. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ SupportsDLPack โ DLPack data interchange โ โ โ protocol. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ SupportsCAI โ CUDA Array Interface (CAI) โ โ โ protocol. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ Buffer โ Buffer-like object. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ Bottom โ Start of the address โ โ โ range. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ InPlace โ In-place buffer argument. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ Aint โ Address-sized integral โ โ โ type. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ Count โ Integral type for counts. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ Displ โ Integral type for โ โ โ displacements. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ Offset โ Integral type for offsets. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ TypeSpec โ Datatype specification. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ BufSpec โ Buffer specification. โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ BufSpecB โ Buffer specification โ โ โ (block). โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ BufSpecV โ Buffer specification โ โ โ (vector). โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ BufSpecW โ Buffer specification โ โ โ (generalized). โ โโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ TargetSpec โ Target specification. โ โโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Types Documentation ๐
๐ฆ mpi4py.typing.SupportsBuffer = <class 'mpi4py.typing.SupportsBuffer'>
Python buffer protocol. ๐ง
See also:
- Buffer Protocol <https://docs.python.org/3/c-api/buffer.html#bufferobjects>
๐ฆ mpi4py.typing.SupportsDLPack = <class 'mpi4py.typing.SupportsDLPack'>
DLPack data interchange protocol. ๐
See also:
dlpack:python-spec
๐ฆ mpi4py.typing.SupportsCAI = <class 'mpi4py.typing.SupportsCAI'>
CUDA Array Interface (CAI) protocol. โก
See also:
numba:cuda-array-interface
๐ฆ mpi4py.typing.Buffer = mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI
Buffer-like object. ๐ซถ
๐ฆ mpi4py.typing.Bottom = mpi4py.MPI.BottomType | None
Start of the address range. ๐
๐ฆ mpi4py.typing.InPlace = mpi4py.MPI.InPlaceType | None
In-place buffer argument. โจ
๐ฆ mpi4py.typing.Aint = <class 'typing.SupportsIndex'>
Address-sized integral type. ๐
alias of SupportsIndex <https://docs.python.org/3/library/typing.html#typing.SupportsIndex>
๐ฆ mpi4py.typing.Count = <class 'typing.SupportsIndex'>
Integral type for counts. ๐ข
alias of SupportsIndex <https://docs.python.org/3/library/typing.html#typing.SupportsIndex>
๐ฆ mpi4py.typing.Displ = <class 'typing.SupportsIndex'>
Integral type for displacements. ๐
alias of SupportsIndex <https://docs.python.org/3/library/typing.html#typing.SupportsIndex>
๐ฆ mpi4py.typing.Offset = <class 'typing.SupportsIndex'>
Integral type for offsets. ๐งฎ
alias of SupportsIndex <https://docs.python.org/3/library/typing.html#typing.SupportsIndex>
๐ฆ mpi4py.typing.TypeSpec = mpi4py.MPI.Datatype | str
Datatype specification. ๐
๐ฆ mpi4py.typing.BufSpec = mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI | typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI, typing.SupportsIndex] | typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI, mpi4py.MPI.Datatype | str] | typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI, typing.SupportsIndex, mpi4py.MPI.Datatype | str] | typing.Tuple[mpi4py.MPI.BottomType | None, typing.SupportsIndex, mpi4py.MPI.Datatype] | typing.List[typing.Any]
Buffer specification. ๐
BufferTuple[Buffer, Count]Tuple[Buffer, TypeSpec]Tuple[Buffer, Count, TypeSpec]Tuple[Bottom, Count, Datatype <#mpi4py.MPI.Datatype>]
๐ฆ mpi4py.typing.BufSpecB = mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI | typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI, typing.SupportsIndex] | typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI, mpi4py.MPI.Datatype | str] | typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI, typing.SupportsIndex, mpi4py.MPI.Datatype | str] | typing.List[typing.Any]
Buffer specification (block). ๐งฑ
BufferTuple[Buffer, Count]Tuple[Buffer, TypeSpec]Tuple[Buffer, Count, TypeSpec]
mpi4py.typing.BufSpecV
okay bestie, this one is the buffer-spec-but-vectorized situation, and yes it's a whole paragraph of union types, but we do NOT skip it, we eat it ๐
mpi4py.typing.BufSpecV = mpi4py.typing.SupportsBuffer |
mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI |
typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack
| mpi4py.typing.SupportsCAI, typing.Sequence[typing.SupportsIndex]] |
typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack
| mpi4py.typing.SupportsCAI,
typing.Tuple[typing.Sequence[typing.SupportsIndex],
typing.Sequence[typing.SupportsIndex]]] |
typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack
| mpi4py.typing.SupportsCAI, mpi4py.MPI.Datatype | str] |
typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack
| mpi4py.typing.SupportsCAI, typing.Sequence[typing.SupportsIndex],
mpi4py.MPI.Datatype | str] | typing.Tuple[mpi4py.typing.SupportsBuffer |
mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI,
typing.Tuple[typing.Sequence[typing.SupportsIndex],
typing.Sequence[typing.SupportsIndex]], mpi4py.MPI.Datatype | str] |
typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack
| mpi4py.typing.SupportsCAI, typing.Sequence[typing.SupportsIndex],
typing.Sequence[typing.SupportsIndex], mpi4py.MPI.Datatype | str] |
typing.Tuple[mpi4py.MPI.BottomType | None,
typing.Tuple[typing.Sequence[typing.SupportsIndex],
typing.Sequence[typing.SupportsIndex]], mpi4py.MPI.Datatype] |
typing.Tuple[mpi4py.MPI.BottomType | None,
typing.Sequence[typing.SupportsIndex],
typing.Sequence[typing.SupportsIndex], mpi4py.MPI.Datatype] |
typing.List[typing.Any]
Buffer specification (vector). periodt. And here's the whole roster of shapes it can take, no gatekeeping:
- Buffer
- Tuple[Buffer, Sequence[Count]]
- Tuple[Buffer, Tuple[Sequence[Count], Sequence[Displ]]]
- Tuple[Buffer, TypeSpec]
- Tuple[Buffer, Sequence[Count], TypeSpec]
- Tuple[Buffer, Tuple[Sequence[Count], Sequence[Displ]], TypeSpec]
- Tuple[Buffer, Sequence[Count], Sequence[Displ], TypeSpec]
- Tuple[Bottom, Tuple[Sequence[Count], Sequence[Displ]], Datatype <#mpi4py.MPI.Datatype>]
- Tuple[Bottom, Sequence[Count], Sequence[Displ], Datatype <#mpi4py.MPI.Datatype>]
mpi4py.typing.BufSpecW
and THIS one is the generalized version, the glow-up, the โจdeluxeโจ buffer spec ๐
mpi4py.typing.BufSpecW = typing.Tuple[mpi4py.typing.SupportsBuffer |
mpi4py.typing.SupportsDLPack | mpi4py.typing.SupportsCAI,
typing.Sequence[mpi4py.MPI.Datatype]] |
typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack
| mpi4py.typing.SupportsCAI,
typing.Tuple[typing.Sequence[typing.SupportsIndex],
typing.Sequence[typing.SupportsIndex]],
typing.Sequence[mpi4py.MPI.Datatype]] |
typing.Tuple[mpi4py.typing.SupportsBuffer | mpi4py.typing.SupportsDLPack
| mpi4py.typing.SupportsCAI, typing.Sequence[typing.SupportsIndex],
typing.Sequence[typing.SupportsIndex],
typing.Sequence[mpi4py.MPI.Datatype]] |
typing.Tuple[mpi4py.MPI.BottomType | None,
typing.Tuple[typing.Sequence[typing.SupportsIndex],
typing.Sequence[typing.SupportsIndex]],
typing.Sequence[mpi4py.MPI.Datatype]] |
typing.Tuple[mpi4py.MPI.BottomType | None,
typing.Sequence[typing.SupportsIndex],
typing.Sequence[typing.SupportsIndex],
typing.Sequence[mpi4py.MPI.Datatype]] | typing.List[typing.Any]
Buffer specification (generalized). And the shapes it accepts, bestie:
- Tuple[Buffer, Sequence[Datatype <#mpi4py.MPI.Datatype>]]
- Tuple[Buffer, Tuple[Sequence[Count], Sequence[Displ]], Sequence[Datatype <#mpi4py.MPI.Datatype>]]
- Tuple[Buffer, Sequence[Count], Sequence[Displ], Sequence[Datatype <#mpi4py.MPI.Datatype>]]
- Tuple[Bottom, Tuple[Sequence[Count], Sequence[Displ]], Sequence[Datatype <#mpi4py.MPI.Datatype>]]
- Tuple[Bottom, Sequence[Count], Sequence[Displ], Sequence[Datatype <#mpi4py.MPI.Datatype>]]
mpi4py.typing.TargetSpec
the one that tells everyone where to aim, no cap ๐ฏ
mpi4py.typing.TargetSpec = typing.SupportsIndex | typing.Tuple[()] |
typing.Tuple[typing.SupportsIndex] | typing.Tuple[typing.SupportsIndex,
typing.SupportsIndex] | typing.Tuple[typing.SupportsIndex,
typing.SupportsIndex, mpi4py.MPI.Datatype | str] |
typing.List[typing.Any]
Target specification. And the vibes it comes in:
- Displ
- Tuple[()]
- Tuple[Displ]
- Tuple[Displ, Count]
- Tuple[Displ, Count, TypeSpec]
mpi4py.typing.S
mpi4py.typing.S = TypeVar("S")
Invariant TypeVar <https://docs.python.org/3/library/typing.html#typing.TypeVar>. That's it, that's the whole thing ๐ซถ
mpi4py.typing.T
mpi4py.typing.T = TypeVar("T")
Invariant TypeVar <https://docs.python.org/3/library/typing.html#typing.TypeVar>.
mpi4py.typing.U
mpi4py.typing.U = TypeVar("U")
Invariant TypeVar <https://docs.python.org/3/library/typing.html#typing.TypeVar>.
mpi4py.typing.V
mpi4py.typing.V = TypeVar("V")
Invariant TypeVar <https://docs.python.org/3/library/typing.html#typing.TypeVar>.
๐ MPI4PY.FUTURES ๐
Added in version 3.0.0.
okay so THIS package is the one that lets you run callables asynchronously on a whole pool of worker processes, using MPI for the inter-process communication. it's giving main character energy for your parallel code ๐ฅ
The mpi4py.futures package is based on concurrent.futures <https://docs.python.org/3/library/concurrent.futures.html#module-concurrent.futures> from the Python standard library. More precisely, mpi4py.futures provides the MPIPoolExecutor class as a concrete implementation of the abstract class Executor <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor>. The submit() <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor.submit> interface schedules a callable to be executed asynchronously and returns a Future <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Future> object representing the execution of the callable. Future <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Future> instances can be queried for the call result or exception. Sets of Future <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Future> instances can be passed to the wait() <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.wait> and as_completed() <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.as_completed> functions.
See also:
- Module
concurrent.futures<https://docs.python.org/3/library/concurrent.futures.html#module-concurrent.futures> โ Documentation of theconcurrent.futures<https://docs.python.org/3/library/concurrent.futures.html#module-concurrent.futures> standard module.
MPIPoolExecutor
The MPIPoolExecutor class uses a pool of MPI processes to execute calls asynchronously. By performing computations in separate processes, it allows to side-step the global interpreter lock <https://docs.python.org/3/glossary.html#term-global-interpreter-lock> but also means that only picklable objects can be executed and returned. The __main__ <https://docs.python.org/3/library/__main__.html#module-__main__> module must be importable by worker processes, thus MPIPoolExecutor instances may not work in the interactive interpreter. ๐ญ (yeah, RIP to REPL girlies, we know)
MPIPoolExecutor takes advantage of the dynamic process management features introduced in the MPI-2 standard. In particular, the MPI.Intracomm.Spawn <#mpi4py.MPI.Intracomm.Spawn> method of MPI.COMM_SELF <#mpi4py.MPI.COMM_SELF> is used in the master (or parent) process to spawn new worker (or child) processes running a Python interpreter. The master process uses a separate thread (one for each MPIPoolExecutor instance) to communicate back and forth with the workers. The worker processes serve the execution of tasks in the main (and only) thread until they are signaled for completion. iconic behavior honestly ๐
Note: The worker processes must import the main script in order to unpickle any callable defined in the__main__<https://docs.python.org/3/library/__main__.html#module-__main__> module and submitted from the master process. Furthermore, the callables may need access to other global variables. At the worker processes,mpi4py.futuresexecutes the main script code (using therunpy<https://docs.python.org/3/library/runpy.html#module-runpy> module) under the__worker__namespace to define the__main__<https://docs.python.org/3/library/__main__.html#module-__main__> module. The__main__<https://docs.python.org/3/library/__main__.html#module-__main__> and__worker__modules are added tosys.modules<https://docs.python.org/3/library/sys.html#sys.modules> (both at the master and worker processes) to ensure proper pickling and unpickling.
Warning: During the initial import phase at the workers, the main script cannot create and use newMPIPoolExecutorinstances. Otherwise, each worker would attempt to spawn a new pool of workers, leading to infinite recursion.mpi4py.futuresdetects such recursive attempts to spawn new workers and aborts the MPI execution environment. As the main script code is run under the__worker__namespace, the easiest way to avoid spawn recursion is using the idiomif __name__ == '__main__': ...in the main script. ๐ do NOT skip this one bestie, infinite recursion is not the serve you think it is
class mpi4py.futures.MPIPoolExecutor(max_workers=None, initializer=None, initargs=(), **kwargs)
class mpi4py.futures.MPIPoolExecutor(max_workers=None, initializer=None,
initargs=(), **kwargs)
An Executor <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor> subclass that executes calls asynchronously using a pool of at most max_workers processes. If max_workers is None <https://docs.python.org/3/library/constants.html#None> or not given, its value is determined from the MPI4PY_FUTURES_MAX_WORKERS environment variable if set, or the MPI universe size if set, otherwise a single worker process is spawned. If max_workers is lower than or equal to 0, then a ValueError <https://docs.python.org/3/library/exceptions.html#ValueError> will be raised. ๐ซ
initializer is an optional callable that is called at the start of each worker process before executing any tasks; initargs is a tuple of arguments passed to the initializer. If initializer raises an exception, all pending tasks and any attempt to submit new tasks to the pool will raise a BrokenExecutor <https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.BrokenExecutor> exception. ๐ตโ๐ซ yeah, that's a whole mood ruiner.
Other parameters:
python_exeโ Path to the Python interpreter executable used to spawn worker processes, otherwisesys.executable<https://docs.python.org/3/library/sys.html#sys.executable> is used.
okay so, bestie, here are the extra kwargs you can pass to MPIPoolExecutor ๐
python_argsโ alistor iterable with additional command line flags to pass to the Python executable. Command line flags determined from inspection ofsys.flags,sys.warnoptionsandsys._xoptionsare passed unconditionally. โจmpi_infoโ adictor iterable yielding(key, value)pairs. These(key, value)pairs are passed (through anMPI.Infoobject) to theMPI.Intracomm.Spawncall used to spawn worker processes. This mechanism allows telling the MPI runtime system where and how to start the processes. Check the documentation of the backend MPI implementation about the set of keys it interprets and the corresponding format for values. ๐globalsโ adictor iterable yielding(name, value)pairs to initialize the main module namespace in worker processes. ๐ธmainโ If set toFalse, do not import the__main__module in worker processes. SettingmaintoFalseprevents worker processes from accessing definitions in the parent__main__namespace. ๐ซถpathโ alistor iterable with paths to append tosys.pathin worker processes to extend the module search path. ๐ฆwdirโ Path to set the current working directory in worker processes usingos.chdir(). The initial working directory is set by the MPI implementation. Quality MPI implementations should honor awdirinfo key passed throughmpi_info, although such feature is not mandatory. ๐ญenvโ adictor iterable yielding(name, value)pairs with environment variables to updateos.environin worker processes. The initial environment is set by the MPI implementation. MPI implementations may allow setting the initial environment throughmpi_info, however such feature is not required nor recommended by the MPI standard. ๐use_pkl5โ If set toTrue, usepicklewith out-of-band buffers for interprocess communication. Ifuse_pkl5is set toNoneor not given, its value is determined from theMPI4PY_FUTURES_USE_PKL5environment variable. Usingpicklewith out-of-band buffers may benefit applications dealing with large buffer-like objects like NumPy arrays. Seempi4py.util.pkl5for additional information. ๐ฅbackoffโ afloatvalue specifying the maximum number of seconds a worker thread or process suspends execution withtime.sleep()while idle-waiting. If not set, its value is determined from theMPI4PY_FUTURES_BACKOFFenvironment variable if set, otherwise the default value of0.001seconds is used. Lower values will reduce latency and increase execution throughput for very short-lived tasks, albeit at the expense of spinning CPU cores and increased energy consumption. ๐
โจ submit(fn, /, *args, **kwargs) โจ
Schedule the callable fn to be executed as fn(*args, **kwargs) and returns a Future object representing the execution of the callable. ๐
executor = MPIPoolExecutor(max_workers=1)
future = executor.submit(pow, 321, 1234)
print(future.result())
โจ map(fn, *iterables, timeout=None, chunksize=1, buffersize=None, **kwargs) โจ
Similar to map(fn, *iterables) except:
- The iterables are consumed immediately rather than lazily, unless
buffersizeis specified to limit the number of submitted tasks whose results have not yet been yielded. If the task buffer is full, the caller blocks and iteration over the iterables pauses until a result is yielded from the buffer. ๐ข fnis executed asynchronously and several calls tofnmay be made concurrently, out-of-order, in separate processes. ๐
The returned iterator raises a TimeoutError if __next__() is called and the result isnโt available after timeout seconds from the original call to map(). timeout can be an int or a float. If timeout is not specified or None, there is no limit to the wait time. โณ
If fn raises an exception, then that exception will be raised when its value is retrieved from the iterator. ๐ฑ
This method chops iterables into a number of chunks which it submits to the pool as separate tasks. The (approximate) size of these chunks can be specified by setting chunksize to a positive integer. For very long iterables, using a large value for chunksize can significantly improve performance compared to the default size of one. ๐ฐ
By default, the returned iterator yields results in-order, waiting for successive tasks to complete. This behavior can be changed by passing the keyword argument unordered as True, then the result iterator will yield a result as soon as any of the tasks complete. ๐ข
executor = MPIPoolExecutor(max_workers=3)
for result in executor.map(pow, [2] * 32, range(32)):
print(result)
Changed in version 4.1.0: Added the buffersize parameter. ๐
โจ starmap(fn, iterable, timeout=None, chunksize=1, buffersize=None, **kwargs) โจ
Similar to itertools.starmap(fn, iterable). Used instead of map() when argument parameters are already grouped in tuples from a single iterable (the data has been โpre-zippedโ). map(fn, *iterable) is equivalent to starmap(fn, zip(*iterable)). ๐
executor = MPIPoolExecutor(max_workers=3)
iterable = ((2, n) for n in range(32))
for result in executor.starmap(pow, iterable):
print(result)
Changed in version 4.1.0: Added the buffersize parameter. ๐
โจ shutdown(wait=True, cancel_futures=False) โจ
Signal the executor that it should free any resources that it is using when the currently pending futures are done executing. Calls to submit() and map() made after shutdown() will raise RuntimeError. ๐
If wait is True then this method will not return until all the pending futures are done executing and the resources associated with the executor have been freed. If wait is False then this method will return immediately and the resources associated with the executor will be freed when all pending futures are done executing. Regardless of the value of wait, the entire Python program will not exit until all pending futures are done executing. โธ๏ธ
If cancel_futures is True, this method will cancel all pending futures that the executor has not started running. Any futures that are completed or running wonโt be cancelled, regardless of the value of cancel_futures. ๐ซ
You can avoid having to call this method explicitly if you use the with statement, which will shutdown the executor instance (waiting as if shutdown() were called with wait set to True). ๐
import time
with MPIPoolExecutor(max_workers=1) as executor:
future = executor.submit(time.sleep, 2)
assert future.done()
bootup(wait=True)โ tells the executor to go ahead and allocate all the resources it needs eagerly, like right now, no waiting (especially the MPI worker processes, they're the whole point ๐ ). IfwaitisTrue<https://docs.python.org/3/library/constants.html#True>, thenbootup()literally will not come back until the executor's resources are ready to handle submissions. But here's the thing โ resources get allocated automatically on the first call tosubmit(), so callingbootup()yourself is seldom needed. It's giving optional, bestie. โจnum_workersโ number of worker processes in the pool. ๐ซถ
๐ MPI4PY_FUTURES_MAX_WORKERS
If the max_workers parameter to MPIPoolExecutor is None <https://docs.python.org/3/library/constants.html#None> or you just didn't pass it at all (no judgment ๐), then the MPI4PY_FUTURES_MAX_WORKERS environment variable steps in as the fallback value for the maximum number of MPI worker processes to spawn. iykyk.
Added in version 3.1.0.
๐ฆ MPI4PY_FUTURES_USE_PKL5
If the use_pkl5 keyword argument to MPIPoolExecutor is None <https://docs.python.org/3/library/constants.html#None> or not given, the MPI4PY_FUTURES_USE_PKL5 environment variable provides a fallback value for whether the executor should use pickle <https://docs.python.org/3/library/pickle.html#module-pickle> with out-of-band buffers for interprocess communication.
Accepted values are:
0and1โ interpreted asFalse<https://docs.python.org/3/library/constants.html#False> andTrue<https://docs.python.org/3/library/constants.html#True>, respectively. yes bestie, exactly like that ๐- strings specifying a YAML boolean <https://yaml.org/type/bool.html> value, and these are case-insensitive.
Using pickle <https://docs.python.org/3/library/pickle.html#module-pickle> with out-of-band buffers may benefit applications dealing with large buffer-like objects like NumPy arrays. See mpi4py.util.pkl5 <#module-mpi4py.util.pkl5> for additional information. ๐ฅ
Added in version 4.0.0.
๐ MPI4PY_FUTURES_BACKOFF
If the backoff keyword argument to MPIPoolExecutor is not given, the MPI4PY_FUTURES_BACKOFF environment variable can be set to a float <https://docs.python.org/3/library/functions.html#float> value specifying the maximum number of seconds a worker thread or process suspends execution with time.sleep() <https://docs.python.org/3/library/time.html#time.sleep> while idle-waiting.
If it's not set, the default backoff value is 0.001 seconds. Lower values will reduce latency and increase execution throughput for very short-lived tasks โ but at the expense of spinning CPU cores and increased energy consumption. so like, trade-offs, it's giving chaos vs. efficiency ๐
Added in version 4.0.0.
Note: ๐ As the master process uses a separate thread to perform MPI communication with the workers, the backend MPI implementation should provide support forMPI.THREAD_MULTIPLE<#mpi4py.MPI.THREAD_MULTIPLE>. However, some popular MPI implementations do not support yet concurrent MPI calls from multiple threads. Additionally, users may decide to initialize MPI with a lower level of thread support. If the level of thread support in the backend MPI is less thanMPI.THREAD_MULTIPLE<#mpi4py.MPI.THREAD_MULTIPLE>,mpi4py.futureswill use a global lock to serialize MPI calls. If the level of thread support is less thanMPI.THREAD_SERIALIZED<#mpi4py.MPI.THREAD_SERIALIZED>,mpi4py.futureswill emit aRuntimeWarning<https://docs.python.org/3/library/exceptions.html#RuntimeWarning>.
Warning: โ ๏ธ If the level of thread support in the backend MPI is less thanMPI.THREAD_SERIALIZED<#mpi4py.MPI.THREAD_SERIALIZED> (i.e, it is eitherMPI.THREAD_SINGLE<#mpi4py.MPI.THREAD_SINGLE> orMPI.THREAD_FUNNELED<#mpi4py.MPI.THREAD_FUNNELED>), in theorympi4py.futurescannot be used. Rather than raising an exception,mpi4py.futuresemits a warning and takes a โcross-fingersโ attitude ๐ค to continue execution in the hope that serializing MPI calls with a global lock will actually work. iconic behaviour honestly.
๐ MPICommExecutor
So like, legacy MPI-1 implementations (and also some vendor MPI-2 implementations, not naming names ๐
) do not support the dynamic process management features introduced in the MPI-2 standard. And on top of that, job schedulers and batch systems in supercomputing facilities may pose additional complications to applications using the MPI_Comm_spawn() routine. it's giving suffering.
With these issues in mind, mpi4py.futures supports an additional, more traditional, SPMD-like usage pattern requiring MPI-1 calls only. Python applications are started the usual way, e.g., using the mpiexec command. Python code should make a collective call to the MPICommExecutor context manager to partition the set of MPI processes within a MPI communicator in one master processes and many workers processes. The master process gets access to an MPIPoolExecutor instance to submit tasks. Meanwhile, the worker process follow a different execution path and team-up to execute the tasks submitted from the master. slay, teamwork fr fr ๐ซถ
Besides alleviating the lack of dynamic process management features in legacy MPI-1 or partial MPI-2 implementations, the MPICommExecutor context manager may be useful in classic MPI-based Python applications willing to take advantage of the simple, task-based, master/worker approach available in the mpi4py.futures package.
class mpi4py.futures.MPICommExecutor(comm=None, root=0)
Context manager for MPIPoolExecutor. This context manager splits a MPI (intra)communicator comm (defaults to MPI.COMM_WORLD <#mpi4py.MPI.COMM_WORLD> if not provided or None <https://docs.python.org/3/library/constants.html#None>) in two disjoint sets: a single master process (with rank root in comm) and the remaining worker processes. These sets are then connected through an intercommunicator.
The target of the with <https://docs.python.org/3/reference/compound_stmts.html#with> statement is assigned either an MPIPoolExecutor instance (at the master) or None <https://docs.python.org/3/library/constants.html#None> (at the workers). bestie the workers get nothing, that's literally the deal ๐
from mpi4py import MPI
from mpi4py.futures import MPICommExecutor
with MPICommExecutor(MPI.COMM_WORLD, root=0) as executor:
if executor is not None:
future = executor.submit(abs, -42)
assert future.result() == 42
answer = set(executor.map(abs, [-42, 42]))
assert answer == {42}
Warning: โ ๏ธ IfMPICommExecutoris passed a communicator of size one (e.g.,MPI.COMM_SELF<#mpi4py.MPI.COMM_SELF>), then the executor instance assigned to the target of thewith<https://docs.python.org/3/reference/compound_stmts.html#with> statement will execute all submitted tasks in a single worker thread, thus ensuring that task execution still progress asynchronously. However, the GIL <https://docs.python.org/3/glossary.html#term-GIL> will prevent the main and worker threads from running concurrently in multicore processors. Moreover, the thread context switching may harm noticeably the performance of CPU-bound tasks. In case of I/O-bound tasks, the GIL <https://docs.python.org/3/glossary.html#term-GIL> is not usually an issue, however, as a single worker thread is used, it progress one task at a time. We advice against usingMPICommExecutorwith communicators of size one and suggest refactoring your code to use instead aThreadPoolExecutor<https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor>. don't do it, we're begging ๐
๐ Command line
Recalling the issues related to the lack of support for dynamic process management features in MPI implementations (yeah, the whole saga from before ๐ญ), mpi4py.futures supports an alternative usage pattern where Python code (either from scripts, modules, or zip files) is run under command line control of the mpi4py.futures package by passing -m mpi4py.futures to the python executable.
The mpi4py.futures invocation should be passed a pyfile path to a script (or a zipfile/directory containing a __main__.py file). Additionally, mpi4py.futures accepts -m mod to execute a module named mod, -c cmd to execute a command string cmd, or even - to read commands from standard input (sys.stdin <https://docs.python.org/3/library/sys.html#sys.stdin>). Summarizing, mpi4py.futures can be invoked in the following ways:
$ mpiexec -n numprocs python -m mpi4py.futures pyfile [arg] ...$ mpiexec -n numprocs python -m mpi4py.futures -m mod [arg] ...$ mpiexec -n numprocs python -m mpi4py.futures -c cmd [arg] ...$ mpiexec -n numprocs python -m mpi4py.futures - [arg] ...
Before starting the main script execution, mpi4py.futures splits MPI.COMM_WORLD <#mpi4py.MPI.COMM_WORLD> in one master (the process with rank 0 in MPI.COMM_WORLD <#mpi4py.MPI.COMM_WORLD>) and numprocs - 1 workers and connects them through an MPI intercommunicator.
Afterwards, the master process proceeds with the execution of the user script code, which eventually creates MPIPoolExecutor instances to submit tasks. Meanwhile, the worker processes follow a different execution path to serve the master. Upon successful termination of the main script at the master, the entire MPI execution environment exists gracefully. In case of any unhandled exception in the main script, the master process calls MPI.COMM_WORLD.Abort(1) to prevent deadlocks and force termination of entire MPI execution environment. yeah it just nukes everything, respectfully ๐ฅ
Warning: โ ๏ธ Running scripts under command line control ofmpi4py.futuresis quite similar to executing a single-process application that spawn additional workers as required. However, there is a very important difference users should be aware of. AllMPIPoolExecutorinstances created at the master will share the pool of workers. Tasks submitted at the master from many different executors will be scheduled for execution in random order as soon as a worker is idle. Any executor can easily starve all the workers (e.g., by callingMPIPoolExecutor.map()with long iterables). If that ever happens, submissions from other executors will not be serviced until free workers are available. lowkey terrifying ngl ๐ญ
See also: ๐
Command line <https://docs.python.org/3/using/cmdline.html#using-on-cmdline> : Documentation on Python command line interface.
โจ Parallel tasks โจ
Okay bestie, plot twist incoming ๐
โ the mpi4py.futures package is normally all about that embarrassingly parallel life: a whole bunch of sequential tasks that don't care about each other, running asynchronously, living their own truth. But! Even though it's kind of not what it was built for, MPIPoolExecutor can still handle workloads that involve parallel tasks โ the kind where worker processes actually talk to each other and coordinate via MPI. It's giving "we're all in this together" energy ๐ซถ
mpi4py.futures.get_comm_workers()โ grab yourself an intracommunicator that groups the MPI worker processes together.
Now, running parallel tasks with mpi4py.futures comes with RULES, bestie. You don't just vibe your way through this one โ check the highlighted lines in the example cpi.py:
- Use
MPIPoolExecutor.num_workersto figure out how many worker processes the executor has, then submit exactly one callable per worker process using theMPIPoolExecutor.submit()method. One each. No double-dipping. ๐ - The callable you submit has to use
get_comm_workers()to get that intracommunicator grouping the MPI worker processes. And then? Highly recommend calling theBarrier()method on the communicator. Why? Because that barrier synchronization is what guarantees every single worker process is executing the submitted callable exactly once โจ. After that's locked in, the parallel task can safely do literally any kind of point-to-point or collective operation using the returned communicator. Iconic. - The
Futureinstances thatMPIPoolExecutor.submit()hands back should be collected into a sequence. Then usewait()with that sequence ofFutureinstances to make sure the parallel task is logically complete. Periodt.
๐งฐ Utilities ๐งฐ
The mpi4py.futures package also hooks you up with some extra utilities for wrangling Future instances ๐
mpi4py.futures.collect(fs)โ gather a whole collection of futures into one shiny new future.
Parameters
- fs โ Collection of futures.
Returns
- New future producing as result a list with results from fs.
mpi4py.futures.compose(future, resulthook=None, excepthook=None)โ compose the completion of a future with result and exception handlers. Very "main character orchestrating her own plot" of it.
Parameters
- future โ Input future instance.
- resulthook โ Function to be called once the input future completes with success. Once the input future finish running with success, its result value is the input argument for resulthook. The result of resulthook is set as the result of the output future. If resulthook is
None, the output future is completed directly with the result of the input future. - excepthook โ Function to be called once the input future completes with failure. Once the input future finish running with failure, its exception value is the input argument for excepthook. If excepthook returns an
Exceptioninstance, it is set as the exception of the output future. Otherwise, the result of excepthook is set as the result of the output future. If excepthook isNone, the output future is set as failed with the exception from the input future.
Returns
- Output future instance to be completed once the input future is completed and either resulthook or excepthook finish executing.
๐ Examples ๐
๐จ Computing the Julia set ๐จ
So the julia.py script below computes the Julia set and dumps an image to disk in binary PGM format. Let's walk through it, bestie ๐ธ
First it imports MPIPoolExecutor from the mpi4py.futures package. Then there's some global constants and functions implementing the Julia set computation. All the computation is protected with the standard if __name__ == '__main__': ... idiom (you know the one, don't skip it ๐). The image gets computed scanline by scanline โ wait, whole scanlines โ submitting all these tasks at once using the map method. The result iterator yields scanlines in-order as the tasks complete. And finally, each scanline is dumped to disk. Slay.
julia.py
from mpi4py.futures import MPIPoolExecutor
x0, x1, w = -2.0, +2.0, 640*2
y0, y1, h = -1.5, +1.5, 480*2
dx = (x1 - x0) / w
dy = (y1 - y0) / h
c = complex(0, 0.65)
def julia(x, y):
z = complex(x, y)
n = 255
while abs(z) < 3 and n > 1:
z = z**2 + c
n -= 1
return n
def julia_line(k):
line = bytearray(w)
y = y1 - k * dy
for j in range(w):
x = x0 + j * dx
line[j] = julia(x, y)
return line
if __name__ == '__main__':
with MPIPoolExecutor() as executor:
image = executor.map(julia_line, range(h))
with open('julia.pgm', 'wb') as f:
f.write(b'P5 %d %d %d\n' % (w, h, 255))
for line in image:
f.write(line)
The recommended way to run this script? Use the mpiexec command, specifying one MPI process (the master) and โ optional but recommended, bestie, do it โ the desired MPI universe size. That universe size determines how many additional dynamically spawned processes (the workers) you get. The MPI universe size comes either from a batch system or gets set by the user via command-line arguments to mpiexec, or via environment variables. Below are examples for MPICH and Open MPI implementations [1].
In all of these examples, the mpiexec command launches a single master process running the Python interpreter and executing the main script. When required, mpi4py.futures spawns the pool of 16 worker processes. The master submits tasks to the workers and waits for the results. The workers receive incoming tasks, execute them, and send back the results to the master. That's the whole little ecosystem, it's giving community ๐
When using the MPICH implementation or its derivatives based on the Hydra process manager, users can set the MPI universe size via the -usize argument to mpiexec:
$ mpiexec -n 1 -usize 17 python julia.py
or, alternatively, by setting the MPIEXEC_UNIVERSE_SIZE environment variable:
$ env MPIEXEC_UNIVERSE_SIZE=17 mpiexec -n 1 python julia.py
In the Open MPI implementation, the MPI universe size can be set via the -host argument to mpiexec:
$ mpiexec -n 1 -host localhost:17 python julia.py
Another way to specify the number of workers is to use the mpi4py.futures-specific environment variable MPI4PY_FUTURES_MAX_WORKERS:
$ env MPI4PY_FUTURES_MAX_WORKERS=16 mpiexec -n 1 python julia.py
Heads up bestie! ๐ Note that in this case, the MPI universe size is ignored. Like, fully ignored. Don't come for me.
Alternatively, users may decide to execute the script in a more traditional way โ that is, all the MPI processes are started at once. The user script is run under command-line control of mpi4py.futures by passing the -m flag to the python executable:
$ mpiexec -n 17 python -m mpi4py.futures julia.py
As explained previously, the 17 processes are partitioned into one master and 16 workers. The master process executes the main script while the workers execute the tasks submitted by the master. โจ
[1] When using an MPI implementation other than MPICH or Open MPI, please check the documentation of the implementation and/or batch system for the ways to specify the desired MPI universe size.
๐ข Computing Pi (parallel task) ๐ข
The number \pi can be approximated via numerical integration with the simple midpoint rule, that is:
\pi = \int_{0}^{1} \frac{4}{1+x^2} \,dx \approx
\frac{1}{n} \sum_{i=1}^{n} \frac{4}{1 + \left[\frac{1}{n}
\left(i-\frac{1}{2}\right) \right]^2} .
The following cpi.py script computes such approximations using mpi4py.futures with a parallel task involving a collective reduction operation. The highlighted lines correspond to the rules we discussed up in Parallel tasks โ go back and reread them if you need, no shame ๐
cpi.py
import math
import sys
from mpi4py.futures import MPIPoolExecutor, wait
from mpi4py.futures import get_comm_workers
def compute_pi(n):
# Access intracommunicator and synchronize
comm = get_comm_workers()
comm.Barrier()
rank = comm.Get_rank()
size = comm.Get_size()
# Local computation
h = 1.0 / n
s = 0.0
for i in range(rank + 1, n + 1, size):
x = h * (i - 0.5)
s += 4.0 / (1.0 + x**2)
pi_partial = s * h
# Parallel reduce-to-all
pi = comm.allreduce(pi_partial)
# All workers return the same value
return pi
if __name__ == '__main__':
n = int(sys.argv[1]) if len(sys.argv) > 1 else 256
with MPIPoolExecutor() as executor:
# Submit exactly one callable per worker
P = executor.num_workers
fs = [executor.submit(compute_pi, n) for _ in range(P)]
# Wait for all workers to finish
wait(fs)
# Get result from the first future object.
# In this particular example, due to using reduce-to-all,
# all the other future objects hold the same result value.
pi = fs[0].result()
print(
f"pi: {pi:.16f}, error: {abs(pi - math.pi):.3e}",
f"({n:d} intervals, {P:d} workers)",
)
To run in modern MPI-2 mode:
$ env MPI4PY_FUTURES_MAX_WORKERS=4 mpiexec -n 1 python cpi.py 128
pi: 3.1415977398528137, error: 5.086e-06 (128 intervals, 4 workers)
$ env MPI4PY_FUTURES_MAX_WORKERS=8 mpiexec -n 1 python cpi.py 512
pi: 3.1415929714812316, error: 3.179e-07 (512 intervals, 8 workers)
To run in legacy MPI-1 mode:
$ mpiexec -n 5 python -m mpi4py.futures cpi.py 128
pi: 3.1415977398528137, error: 5.086e-06 (128 intervals, 4 workers)
$ mpiexec -n 9 python -m mpi4py.futures cpi.py 512
pi: 3.1415929714812316, error: 3.179e-07 (512 intervals, 8 workers)
๐ Citation ๐
Okay so if mpi4py.futures has been significant to a project that leads to an academic publication, please acknowledge our work by citing the following article [mpi4py-futures]:
[mpi4py-futures]โ M. Rogowski, S. Aseeri, D. Keyes, and L. Dalcin, mpi4py.futures: MPI-Based Asynchronous Task Execution for Python, IEEE Transactions on Parallel and Distributed Systems, 34(2):611-622, 2023.<https://doi.org/10.1109/TPDS.2022.3225481>
๐งฐ MPI4PY.UTIL ๐งฐ
Added in version 3.1.0.
ok so the mpi4py.util package is literally the grab-bag drawer of the whole library โ it collects miscellaneous utilities that live right in the intersection of Python and MPI. bestie, it's giving "junk drawer but make it useful" and honestly? we're obsessed. ๐
๐ mpi4py.util.dtlib ๐
Added in version 3.1.0.
the mpi4py.util.dtlib module is your little translator between NumPy and MPI datatypes โ converter routines, that's the whole job, no cap. โจ
mpi4py.util.dtlib.from_numpy_dtype(dtype)
Convert NumPy datatype to MPI datatype. girl math but for types. ๐ฆ
Parameters
- dtype (
DTypeLike <https://numpy.org/doc/stable/reference/typing.html#numpy.typing.DTypeLike>) โ NumPy dtype-like object.
Return type
Datatype <#mpi4py.MPI.Datatype>
mpi4py.util.dtlib.to_numpy_dtype(datatype)
Convert MPI datatype to NumPy datatype. the reverse pipeline, periodt. ๐
Parameters
- datatype (
Datatype <#mpi4py.MPI.Datatype>) โ MPI datatype.
Return type
dtype <https://numpy.org/doc/stable/reference/generated/numpy.dtype.html#numpy.dtype>[Any <https://docs.python.org/3/library/typing.html#typing.Any>]
๐ฅ mpi4py.util.pkl5 ๐ฅ
Added in version 3.1.0.
so pickle <https://docs.python.org/3/library/pickle.html#module-pickle> protocol 5 (peep PEP 574 <https://peps.python.org/pep-0574/>) rolled in support for out-of-band buffers, which lets you handle certain object types with large memory footprints wayyy more efficiently. it's giving glow-up. โจ
MPI for Python uses the traditional in-band handling of buffers. That approach is appropriate for communicating non-buffer Python objects, or buffer-like objects with small memory footprints. For point-to-point communication, in-band buffer handling lets you communicate a pickled stream with a single MPI message โ at the expense of additional CPU and memory overhead in the pickling and unpickling steps. trade-offs, bestie, always trade-offs. ๐ญ
the mpi4py.util.pkl5 module provides communicator wrapper classes that reimplement pickle-based point-to-point and collective communication methods using pickle protocol 5. Handling out-of-band buffers necessarily involves multiple MPI messages, which increases latency and hurts performance in the case of small size data. BUT. in the case of large size data, the zero-copy savings of out-of-band buffer handling more than offset the extra latency costs. additionally, these wrapper methods overcome the infamous 2 GiB message count limit (MPI-1 to MPI-3). slay. ๐
class mpi4py.util.pkl5.Request
Request.
Custom request class for nonblocking communications.
Note: Request is not a subclass of mpi4py.MPI.Request <#mpi4py.MPI.Request>
Free()โ Free a communication request.- Return type:
None <https://docs.python.org/3/library/constants.html#None>
- Return type:
free()โ Free a communication request.- Return type:
None <https://docs.python.org/3/library/constants.html#None>
- Return type:
cancel()โ Cancel a communication request.- Return type:
None <https://docs.python.org/3/library/constants.html#None>
- Return type:
get_status(status=None)โ Non-destructive test for the completion of a request.- Parameters
- status (
Status <#mpi4py.MPI.Status> | None <https://docs.python.org/3/library/constants.html#None>)
- status (
- Return type:
bool <https://docs.python.org/3/library/functions.html#bool>
- Parameters
test(status=None)โ Test for the completion of a request.- Parameters
- status (
Status <#mpi4py.MPI.Status> | None <https://docs.python.org/3/library/constants.html#None>)
- status (
- Return type:
tuple <https://docs.python.org/3/library/stdtypes.html#tuple>[bool <https://docs.python.org/3/library/functions.html#bool>, Any <https://docs.python.org/3/library/typing.html#typing.Any> | None <https://docs.python.org/3/library/constants.html#None>]
- Parameters
wait(status=None)โ Wait for a request to complete.- Parameters
- status (
Status <#mpi4py.MPI.Status> | None <https://docs.python.org/3/library/constants.html#None>)
- status (
- Return type:
Any <https://docs.python.org/3/library/typing.html#typing.Any>
- Parameters
classmethod get_status_all(requests, statuses=None)โ Non-destructive test for the completion of all requests. Classmethod.classmethod testall(requests, statuses=None)โ Test for the completion of all requests. Classmethod.classmethod waitall(requests, statuses=None)โ Wait for all requests to complete. Classmethod.
class mpi4py.util.pkl5.Message
Message.
Custom message class for matching probes.
Note: Message is not a subclass of mpi4py.MPI.Message <#mpi4py.MPI.Message>
free()โ Do nothing. (literally nothing, it's a freebie ๐)- Return type:
None <https://docs.python.org/3/library/constants.html#None>
- Return type:
recv(status=None)โ Blocking receive of matched message.- Parameters
- status (
Status <#mpi4py.MPI.Status> | None <https://docs.python.org/3/library/constants.html#None>)
- status (
- Return type:
Any <https://docs.python.org/3/library/typing.html#typing.Any>
- Parameters
irecv()โ Nonblocking receive of matched message.- Return type:
Request <#mpi4py.util.pkl5.Request>
- Return type:
classmethod probe(comm, source=ANY_SOURCE, tag=ANY_TAG, status=None)โ Blocking test for a matched message. Classmethod.classmethod iprobe(comm, source=ANY_SOURCE, tag=ANY_TAG, status=None)โ Nonblocking test for a matched message. Classmethod.
class mpi4py.util.pkl5.Comm
Communicator.
Base communicator wrapper class.
send(obj, dest, tag=0)โ Blocking send in standard mode.- Parameters
- Return type:
None <https://docs.python.org/3/library/constants.html#None>
bsend(obj, dest, tag=0)โ Blocking send in buffered mode.- Parameters
- Return type:
None <https://docs.python.org/3/library/constants.html#None>
ssend(obj, dest, tag=0)โ Blocking send in synchronous mode.- Parameters
- Return type:
None <https://docs.python.org/3/library/constants.html#None>
isend(obj, dest, tag=0)โ Nonblocking send in standard mode.- Parameters
- Return type:
Request <#mpi4py.util.pkl5.Request>
ibsend(obj, dest, tag=0)โ Nonblocking send in buffered mode.- Parameters
- Return type:
Request <#mpi4py.util.pkl5.Request>
issend(obj, dest, tag=0)โ Nonblocking send in synchronous mode.- Parameters
- Return type:
Request <#mpi4py.util.pkl5.Request>
recv(buf=None, source=ANY_SOURCE, tag=ANY_TAG, status=None)โ Blocking receive.- Parameters
- buf (
Buffer <#mpi4py.typing.Buffer> | None <https://docs.python.org/3/library/constants.html#None>) - source (
int <https://docs.python.org/3/library/functions.html#int>)
- buf (
- Parameters
tag(int)status(Status|None)
Return type: Any
irecv(buf=None, source=ANY_SOURCE, tag=ANY_TAG)
Nonblocking receive.
๐จ Warning, bestie, listen up: this method cannot be supported reliably and it raises RuntimeError. Like, it's just gonna yell at you. No cap.
Parameters:
buf(Buffer|None)source(int)tag(int)
Return type: Request
sendrecv(sendobj, dest, sendtag=0, recvbuf=None, source=ANY_SOURCE, recvtag=ANY_TAG, status=None)
Send and receive. Both at once, main character energy. ๐
Parameters:
sendobj(Any)dest(int)sendtag(int)recvbuf(Buffer|None)source(int)recvtag(int)status(Status|None)
Return type: Any
mprobe(source=ANY_SOURCE, tag=ANY_TAG, status=None)
Blocking test for a matched message. Sits there and waits like your bestie outside the bathroom. ๐ช
Parameters:
source(int)tag(int)status(Status|None)
Return type: Message
improbe(source=ANY_SOURCE, tag=ANY_TAG, status=None)
Nonblocking test for a matched message. Same vibe, but it does NOT wait around. โจ
Parameters:
source(int)tag(int)status(Status|None)
Return type: Message | None
bcast(obj, root=0)
Broadcast.
Added in version 3.1.0.
Parameters:
obj(Any)root(int)
Return type: Any
gather(sendobj, root=0)
Gather.
Added in version 4.0.0.
Parameters:
sendobj(Any)root(int)
Return type: list[Any] | None
scatter(sendobj, root=0)
Scatter.
Added in version 4.0.0.
Parameters:
sendobj(Sequence[Any]|None)root(int)
Return type: Any
allgather(sendobj)
Gather to All. Everybody gets the tea, nobody's left on read. ๐ซถ
Added in version 4.0.0.
Parameters:
sendobj(Any)
Return type: list[Any]
alltoall(sendobj)
All to All Scatter/Gather. Chaotic in the best way, fr fr. ๐ฅ
Added in version 4.0.0.
Parameters:
sendobj(Sequence[Any])
Return type: list[Any]
class mpi4py.util.pkl5.Intracomm
Intracommunicator.
Intracommunicator wrapper class. It's literally just a lil glow-up wrapper around the comm you already know. ๐
class mpi4py.util.pkl5.Intercomm
Intercommunicator.
Intercommunicator wrapper class. Same energy, different topology. ๐ฆ
โจ Examples โจ
test-pkl5-1.py
import numpy as np
from mpi4py import MPI
from mpi4py.util import pkl5
comm = pkl5.Intracomm(MPI.COMM_WORLD) # comm wrapper
size = comm.Get_size()
rank = comm.Get_rank()
dst = (rank + 1) % size
src = (rank - 1) % size
sobj = np.full(1024**3, rank, dtype='i4') # > 4 GiB
sreq = comm.isend(sobj, dst, tag=42)
robj = comm.recv (None, src, tag=42)
sreq.Free()
assert np.min(robj) == src
assert np.max(robj) == src
test-pkl5-2.py
import numpy as np
from mpi4py import MPI
from mpi4py.util import pkl5
comm = pkl5.Intracomm(MPI.COMM_WORLD) # comm wrapper
size = comm.Get_size()
rank = comm.Get_rank()
dst = (rank + 1) % size
src = (rank - 1) % size
sobj = np.full(1024**3, rank, dtype='i4') # > 4 GiB
sreq = comm.isend(sobj, dst, tag=42)
status = MPI.Status()
rmsg = comm.mprobe(status=status)
assert status.Get_source() == src
assert status.Get_tag() == 42
rreq = rmsg.irecv()
robj = rreq.wait()
sreq.Free()
assert np.max(robj) == src
assert np.min(robj) == src
๐ mpi4py.util.pool ๐
Added in version 4.0.0.
See also:
This module intends to be a drop-in replacement for the multiprocessing.pool interface from the Python standard library. The Pool class exposed here is implemented as a thin wrapper around MPIPoolExecutor. So like, if your code already speaks multiprocessing.pool, it just... works. Slay. ๐
Note:
The mpi4py.futures package offers a higher level interface for asynchronously pushing tasks to MPI worker process, allowing for a clear separation between submitting tasks and waiting for the results. iykyk โ if you want the fancier setup, go there.
class mpi4py.util.pool.Pool
Pool using MPI processes as workers. Your little squad of worker processes, assembled and ready. ๐
__init__(processes=None, initializer=None, initargs=(), **kwargs)
Initialize a new Pool instance.
Parameters:
processes(int|None) โ Number of worker processes.initializer(Callable[[...], object]|None) โ An callable used to initialize workers processes.initargs(Iterable[Any]) โ A tuple of arguments to pass to the initializer.kwargs(Any)
Return type: None
Note:
Additional keyword arguments are passed down to the MPIPoolExecutor constructor. So all that extra stuff you're passing? It goes straight to the executor. Periodt. โจ
Warning, bestie, read this one: themaxtasksperchildandcontextarguments ofmultiprocessing.pool.Poolare not supported. If you passmaxtasksperchildorcontextwith anything other thanNone, you'll get a warning of categoryUserWarning. Not a vibe. Don't do it. ๐ซถ
apply(func, args=(), kwds={})
Calls func with the arguments args and the keyword arguments kwds. โจ
It's literally equivalent to func(*args, **kwds). No cap.
Parameters ๐
funcโ aCallable[[...], T]argsโ anIterable[Any]kwdsโ aMapping[str, Any]
Return type โ T ๐
apply_async(func, args=(), kwds={}, callback=None, error_callback=None)
The asynchronous version of apply(), and it hands you back an ApplyResult. ๐ฆ
Parameters ๐
funcโ aCallable[..., T]argsโ anIterable[Any]kwdsโ aMapping[str, Any]callbackโ aCallable[[T], object] | Noneerror_callbackโ aCallable[[BaseException], object] | None
Return type โ AsyncResult[T] ๐
map(func, iterable, chunksize=None)
Applies func to every single element in iterable. ๐
Equivalent to list(map(func, iterable)).
It blocks until all the results are ready, then returns them in a list. Yes bestie, it will just sit there and wait for you. ๐ง
The iterable gets choped (their spelling, not mine ๐ญ) into a number of chunks which are submitted as separate tasks. The (approximate) size of these chunks can be specified by setting chunksize to a positive integer.
Hot tip from the docs: consider usingimap()orimap_unordered()with an explicitchunksizefor better efficiency. Efficiency is the moment. โญ
Parameters ๐
funcโ aCallable[[S], T]iterableโ anIterable[S]chunksizeโ anint | None
Return type โ list[T] ๐ธ
map_async(func, iterable, chunksize=None, callback=None, error_callback=None)
The asynchronous version of map(), and it hands you back a MapResult. ๐ฆ
Parameters ๐
funcโ aCallable[[S], T]iterableโ anIterable[S]chunksizeโ anint | Nonecallbackโ aCallable[[T], None] | Noneerror_callbackโ aCallable[[BaseException], None] | None
Return type โ MapResult[T] ๐
imap(func, iterable, chunksize=1)
Like map() but it returns an iterator instead of blocking on you. Main character behaviour, honestly. โจ
Equivalent to map(func, iterable).
Parameters ๐
funcโ aCallable[[S], T]iterableโ anIterable[S]chunksizeโ anint
Return type โ Iterator[T] ๐ฆ
imap_unordered(func, iterable, chunksize=1)
Like imap() but the ordering of the results is arbitrary. ๐ฒ
Read that again bestie: arbitrary. The results come back in whatever order they finish, not the order you sent them. If order matters to you, this is not the one. ๐
Parameters ๐
funcโ aCallable[[S], T]iterableโ anIterable[S]chunksizeโ anint
Return type โ Iterator[T] ๐
starmap(func, iterable, chunksize=None)
Applies func to each argument tuple in iterable. ๐
Equivalent to list(itertools.starmap(func, iterable)).
It blocks until all the results are ready and returns them in a list. Patience, queen. ๐
The iterable gets choped into a number of chunks which are submitted as separate tasks. The (approximate) size of these chunks can be specified by setting chunksize to a positive integer.
Same tip as before: consider usingistarmap()oristarmap_unordered()with an explicitchunksizefor better efficiency. ๐ฅ
Parameters ๐
funcโ aCallable[[...], T]iterableโ anIterable[Iterable[Any]]chunksizeโ anint | None
Return type โ list[T] ๐ธ
starmap_async(func, iterable, chunksize=None, callback=None, error_callback=None)
The asynchronous version of starmap(), and it hands you back a MapResult. ๐ฆ
Parameters ๐
funcโ aCallable[..., T]iterableโ anIterable[Iterable[Any]]chunksizeโ anint | Nonecallbackโ aCallable[[T], None] | Noneerror_callbackโ aCallable[[BaseException], None] | None
Return type โ MapResult[T] ๐
istarmap(func, iterable, chunksize=1)
Like starmap() but it returns an iterator. ๐
Equivalent to itertools.starmap(func, iterable).
Parameters ๐
funcโ aCallable[[...], T]
istarmap_unordered(func, iterable, chunksize=1)
okay so bestie, this one is literally istarmap() โ but the ordering of results is arbitrary. They arrive whenever they arrive. chaos as a feature โจ
Parameters
funcโCallable[[...], T]iterableโIterable[Iterable[Any]]chunksizeโint
Return type: Iterator[T]
close()
Prevent any more tasks from being submitted to the pool. doors? closed. that's the whole function ๐
Return type: None
terminate()
Stop the worker processes without completing pending tasks. No cleanup arc, we just end it ๐ญ
Return type: None
join()
Wait for the worker processes to exit. just sit there and let them go, okay? ๐ฆ
Return type: None
class mpi4py.util.pool.ThreadPool
Bases: Pool
A pool that uses threads as its workers. ๐ง
class mpi4py.util.pool.AsyncResult
Asynchronous result. a lil container for a value that hasn't shown up yet ๐
get(timeout=None) โ Return the result when it arrives.
- If
timeoutis notNoneand the result does not arrive withintimeoutseconds then raiseTimeoutError. - If the remote call raised an exception then that exception will be reraised.
Parameters
timeoutโfloat | None
Return type: T
wait(timeout=None) โ Wait until the result is available or timeout seconds pass.
Parameters
timeoutโfloat | None
Return type: None
ready() โ Return whether the call has completed.
Return type: bool
successful() โ Return whether the call completed without raising an exception.
Heads up: if the result is not ready then raise ValueError.
Return type: bool
class mpi4py.util.pool.ApplyResult
Bases: AsyncResult
Result type of apply_async(). ๐
class mpi4py.util.pool.MapResult
Bases: AsyncResult
Result type of map_async() and starmap_async(). ๐
mpi4py.util.sync
Added in version 4.0.0.
The mpi4py.util.sync module provides parallel synchronization utilities. everybody on the same page, together, periodt ๐ซถ
Sequential execution
class mpi4py.util.sync.Sequential โ Sequential execution.
Context manager for sequential execution within a group of MPI processes. one at a time, in rank order, no cutting the line ๐ธ
The implementation is based in MPI-1 point-to-point communication. A process with rank i waits in a blocking receive until the previous process rank i-1 finish executing and signals the next rank i with a send.
__init__(comm, tag=0) โ Initialize sequential execution.
Parameters
commโIntracomm. Intracommunicator context.tagโint. Tag for point-to-point communication.
Return type: None
__enter__() โ Enter sequential execution.
Return type: Self
__exit__(*exc) โ Exit sequential execution.
Parameters
excโobject
Return type: None
begin() โ Begin sequential execution.
Return type: None
end() โ End sequential execution.
Return type: None
Global counter
class mpi4py.util.sync.Counter โ Global counter.
Produce consecutive values within a group of MPI processes. The counter interface is close to that of itertools.count. it's giving "everyone gets a number, nobody gets the same one" โจ
The implementation is based in MPI-3 one-sided operations. A root process (typically rank 0) holds the counter, and its value is queried and incremented with an atomic RMA fetch-and-add operation.
__init__(start=0, step=1, *, typecode='i', comm=COMM_SELF, info=INFO_NULL, root=0) โ Initialize global counter.
Parameters
startโint. Start value.stepโint. Increment value.typecodeโstr. Type code as defined in thearraymodule.commโIntracomm. Intracommunicator context.infoโInfo. Info object for RMA context creation.rootโint. Process rank holding the counter memory.
Return type: None
__iter__() โ Implement iter(self).
Return type: Self
__next__() โ Implement next(self).
Return type: int
next(incr=None) โ Return current value and increment.
Parameters
incrโint | None. Increment value.
Returns: The counter value before incrementing.
Return type: int
free() โ Free counter resources. clean up after yourself, bestie ๐
Return type: None
Mutual exclusion
class mpi4py.util.sync.Mutex โ Mutual exclusion.
Establish a critical section or mutual exclusion among MPI processes.
The mutex interface is close to that of threading.Lock and threading.RLock, allowing the use of either recursive or non-recursive mutual exclusion. However, a mutex should be used within a group of MPI processes, not threads. ๐
In non-recursive mode, the semantics of Mutex are somewhat different than these of threading.Lock:
- Once acquired, a mutex is held and owned by a process until released.
- Trying to acquire a mutex already held raises
RuntimeError. - Trying to release a mutex not yet held raises
RuntimeError.
fr fr, respect the lock: if it's already held and you try to grab it again,RuntimeError. If you try to release something you never held,RuntimeError. No cap. ๐
This mutex implementation uses the scalable and fair spinlock algorithm from [mcs-paper] and took inspiration from the MPI-3 RMA implementation of [uam-book]. Bestie, that's a whole academic glow-up for a lock. ๐
__init__(*, recursive=False, comm=COMM_SELF, info=INFO_NULL)
Initialize mutex object. Yes, constructor, we love a fresh start.
Parameters
comm(Intracomm) โ Intracommunicator context.recursive(bool) โ Whether to allow recursive acquisition.info(Info) โ Info object for RMA context creation.
Return type: None
__enter__()
Acquire mutex. Context manager said "I gotchu". ๐ซถ
Return type: Self
__exit__(*exc)
Release mutex.
Parameters
exc(object)
Return type: None
acquire(blocking=True)
Acquire mutex, blocking or non-blocking. Your choice, main character.
Parameters
blocking(bool) โ IfTrue, block until the mutex is held.
Returns: True if the mutex is held, False otherwise.
Return type: bool
release()
Release mutex. Let it gooo, let it gooo. ๐ฆ
Return type: None
locked()
Return whether the mutex is held. Vibe check: is it locked or not?
Return type: bool
count()
Return the recursion count.
Return type: int
free()
Free mutex resources. Cleanup era โ no leaks, periodt.
Return type: None
[mcs-paper]
John M. Mellor-Crummey and Michael L. Scott. Algorithms for scalable synchronization on shared-memory multiprocessors. ACM Transactions on Computer Systems, 9(1):21-65, February 1991. https://doi.org/10.1145/103727.103729
[uam-book]
William Gropp, Torsten Hoefler, Rajeev Thakur, Ewing Lusk. Using Advanced MPI - Modern Features of the Message-Passing Interface. Chapter 4, Section 4.7, Pages 130-131. The MIT Press, November 2014. https://mitpress.mit.edu/9780262527637/using-advanced-mpi/
๐ Condition variable
class mpi4py.util.sync.Condition
Condition variable.
A condition variable allows one or more MPI processes to wait until they are notified by another processes. It's giving "don't text them first, wait for the notification". ๐
The condition variable interface is close to that of threading.Condition, allowing the use of either recursive or non-recursive mutual exclusion. However, the condition variable should be used within a group of MPI processes, not threads. Read that again, bestie โ processes, not threads. Important.
This condition variable implementation uses a MPI-3 RMA-based scalable and fair circular queue algorithm to track the set of waiting processes. Circular queue, fair, scalable โ she's an overachiever and we respect it. ๐
__init__(mutex=None, *, recursive=True, comm=COMM_SELF, info=INFO_NULL)
Initialize condition variable.
Parameters
mutex(Mutex|None) โ Mutual exclusion object.recursive(bool) โ Whether to allow recursive acquisition.comm(Intracomm) โ Intracommunicator context.info(Info) โ Info object for RMA context creation.
Return type: None
__enter__()
Acquire the underlying mutex.
Return type: Self
__exit__(*exc)
Release the underlying mutex.
Parameters
exc(object)
Return type: None
acquire(blocking=True)
Acquire the underlying mutex.
Parameters
blocking(bool)
Return type: bool
release()
Release the underlying mutex.
Return type: None
locked()
Return whether the underlying mutex is held.
Return type: bool
wait()
Wait until notified by another process. Literally just sitting there, patiently, waiting for a sign. ๐
Returns: Always True.
Return type: Literal[True]
wait_for(predicate)
Wait until a predicate evaluates to True. She waits for the condition to be true, not for a text back. Growth. ๐ธ
Parameters
predicate(Callable[[], T]) โ callable returning a boolean.
Returns: The result of predicate once it evaluates to True.
Return type: T
notify(n=1)
Wake up one or more processes waiting on this condition.
Parameters
n(int) โ Maximum number of processes to wake up.
Returns: The actual number of processes woken up.
Return type: int
notify_all()
Wake up all processes waiting on this condition. Group chat notification, everyone up. ๐
Returns: The actual number of processes woken up.
Return type: int
free()
Free condition resources.
Return type: None
๐ Semaphore object
class mpi4py.util.sync.Semaphore
Semaphore object.
A semaphore object manages an internal counter which is decremented by each acquire() call and incremented by each release() call. The internal counter never reaches a value below zero; when acquire() finds that it is zero, it blocks and waits until some other process calls release(). Counter go down, counter go up, counter never go negative โ she has boundaries. ๐
The semaphore interface is close to that of threading.Semaphore and threading.BoundedSemaphore, allowing the use of either bounded (default) or unbounded semaphores. With a bounded semaphore, the internal counter never exceeds its initial value; otherwise release() raises ValueError. So yeah, unbounded means release() can throw ValueError at you. Not a drill.
This semaphore implementation uses a global Counter and a Condition variable to handle waiting and notification.
__init__(value=1, *, bounded=True, comm=COMM_SELF, info=INFO_NULL)
Initialize semaphore object.
Parameters
value(int) โ Initial value for internal counter.bounded(bool) โ Bound internal counter to initial value.comm(Intracomm) โ Intracommunicator context.info(Info) โ Info object for RMA context creation.
Return type: None
__enter__()
Acquire semaphore.
Return type: Self โ and yes bestie, it literally hands you back Self ๐
so you can keep the chain going
__exit__(*exc)โ let go of the semaphore, we're done here ๐ซถ- exc (
object) - Return type:
None
- exc (
acquire(blocking=True)โ grab the semaphore and knock the internal counter down by one โจ- blocking (
bool) โ ifTrue, just sit there and wait patiently (no cap, it will block) until the semaphore is acquired. - Returns:
Trueif the semaphore is acquired,Falseotherwise. - Return type:
bool
- blocking (
release(n=1)โ release the semaphore, bumping that internal counter up by one or more ๐- n (
int) โ how much to increment the internal counter by. - Return type:
None
- n (
free()โ free semaphore resources, clean up your mess queen ๐งน- Return type:
None
- Return type:
๐งช Examples ๐งช
test-sync-1.py
from mpi4py import MPI
from mpi4py.util.sync import Counter, Sequential
comm = MPI.COMM_WORLD
counter = Counter(comm)
with Sequential(comm):
value = next(counter)
counter.free()
assert comm.rank == value
test-sync-2.py
from mpi4py import MPI
from mpi4py.util.sync import Counter, Mutex
comm = MPI.COMM_WORLD
mutex = Mutex(comm)
counter = Counter(comm)
with mutex:
value = next(counter)
counter.free()
mutex.free()
assert (
list(range(comm.size)) ==
sorted(comm.allgather(value))
)
๐ MPI4PY.RUN ๐
Added in version 3.0.0. โญ
okay so here's the whole vibe ๐ โ at import time, mpi4py initializes the MPI execution environment by calling MPI_Init_thread(), and it installs an exit hook to automatically call MPI_Finalize() right before the Python process terminates. And also, mpi4py overrides the default ERRORS_ARE_FATAL error handler in favor of ERRORS_RETURN, which is what lets it translate MPI errors into Python exceptions ๐ฆ
These departures from standard MPI behavior may be controversial, but honestly? they're quite convenient inside the highly dynamic Python programming environment, iykyk. Third-party code using mpi4py can just from mpi4py import MPI and do MPI calls without that tedious initialization/finalization handling ๐ญ. And MPI errors, once they're automatically translated into Python exceptions, can be dealt with using the usual tryโฆexceptโฆfinally clauses โ unhandled MPI exceptions will print a traceback, which helps you locate problems in your source code ๐
Unfortunately โ and this is the part where we get dramatic โ the interplay of automatic MPI finalization and unhandled exceptions may lead to deadlocks ๐. And in unattended runs, these deadlocks will drain the battery of your laptop, or burn precious allocation hours in your supercomputing facility. Not the allocation hours bestie, NOT the allocation hours ๐ญ
๐ญ Exceptions and deadlocks ๐ญ
Consider the following snippet of Python code. Assume this code is stored in a standard Python script file and run with mpiexec in two or more processes.
deadlock.py
from mpi4py import MPI
assert MPI.COMM_WORLD.Get_size() > 1
rank = MPI.COMM_WORLD.Get_rank()
if rank == 0:
1/0
MPI.COMM_WORLD.send(None, dest=1, tag=42)
elif rank == 1:
MPI.COMM_WORLD.recv(source=0, tag=42)
Process 0 raises a ZeroDivisionError exception before it ever performs a send call to process 1. And because that exception is not handled, the Python interpreter running in process 0 will proceed to exit with non-zero status. BUT โ since mpi4py installed a finalizer hook to call MPI_Finalize() before exit, process 0 will block, waiting for the other processes to also enter the MPI_Finalize() call ๐ณ
Meanwhile, process 1 is blocked waiting for a message to arrive from process 0, so it never reaches MPI_Finalize(). And the whole MPI execution environment is irremediably in a deadlock state ๐๐
To alleviate this issue, mpi4py offers a simple, alternative command line execution mechanism based on using the -m flag and implemented with the runpy module. To use this feature, Python code should be run passing -m mpi4py in the command line invoking the Python interpreter. And in the case of unhandled exceptions, the finalizer hook will call MPI_Abort() on the MPI_COMM_WORLD communicator โ thus effectively aborting the MPI execution environment ๐ฅ
Warning: When a process is forced to abort, resources (e.g. open files) are not cleaned-up and any registered finalizers (either with theatexitmodule, the Python C/API functionPy_AtExit(), or even the C standard library functionatexit()) will not be executed. So likeโฆ aborting execution is an extremely impolite way of ensuring process termination ๐. However, MPI provides no other mechanism to recover from a deadlock state. Periodt.
๐ป Command line ๐ป
Using -m mpi4py to execute Python code on the command line resembles that of the Python interpreter โจ
mpiexec -n numprocs python -m mpi4py pyfile [arg] ...
mpiexec -n numprocs python -m mpi4py -m mod [arg] ...
mpiexec -n numprocs python -m mpi4py -c cmd [arg] ...
mpiexec -n numprocs python -m mpi4py - [arg] ...
<pyfile>โ execute the Python code contained in pyfile, which must be a filesystem path referring to either a Python file, a directory containing a__main__.pyfile, or a zipfile containing a__main__.pyfile. ๐-m <mod>โ searchsys.pathfor the named module mod and execute its contents.-c <cmd>โ execute the Python code in the cmd string command.-โ read commands from standard input (sys.stdin).
See also:
- Command line โ Documentation on Python command line interface. (
https://docs.python.org/3/using/cmdline.html#using-on-cmdline)
๐ธ MPI4PY.BENCH ๐ธ
Added in version 3.0.0. โญ
๐ REFERENCE ๐
mpi4py.MPIโ Message Passing Interface. ๐
๐ mpi4py.MPI ๐
Message Passing Interface.
โจ Classes โจ
okay bestie, here's the whole cast of characters ๐ every class chilling in mpi4py.MPI, lined up so you can meet them all:
mpi4py.MPI.BottomTypeโ type ofBOTTOM.mpi4py.MPI.BufferAutomaticTypeโ type ofBUFFER_AUTOMATIC.mpi4py.MPI.Cartcommโ Cartesian topology intracommunicator.mpi4py.MPI.Commโ communication context.mpi4py.MPI.Datatypeโ datatype object.mpi4py.MPI.Distgraphcommโ distributed graph topology intracommunicator.mpi4py.MPI.Errhandlerโ error handler.mpi4py.MPI.Fileโ file I/O context.mpi4py.MPI.Graphcommโ general graph topology intracommunicator.mpi4py.MPI.Grequestโ generalized request handler.mpi4py.MPI.Groupโ group of processes.mpi4py.MPI.InPlaceTypeโ type ofIN_PLACE.mpi4py.MPI.Infoโ info object.mpi4py.MPI.Intercommโ intercommunicator.mpi4py.MPI.Intracommโ intracommunicator.mpi4py.MPI.Messageโ matched message.mpi4py.MPI.Opโ reduction operation.mpi4py.MPI.Pickleโ pickle/unpickle Python objects.mpi4py.MPI.Prequestโ persistent request handler.mpi4py.MPI.Requestโ request handler.mpi4py.MPI.Sessionโ session context.mpi4py.MPI.Statusโ status object.mpi4py.MPI.Topocommโ topology intracommunicator.mpi4py.MPI.Winโ remote memory access context.mpi4py.MPI.bufferโ buffer.mpi4py.MPI.memoryโ alias ofmpi4py.MPI.buffer.
mpi4py.MPI.BottomType
class mpi4py.MPI.BottomType
Bases: object
It's literally just the type of BOTTOM ๐
that's the whole gig, no notes.
static __new__(cls)
Return type: Self
mpi4py.MPI.BufferAutomaticType
class mpi4py.MPI.BufferAutomaticType
Bases: object
The type of BUFFER_AUTOMATIC โจ a whole vibe, and that vibe is automatic.
static __new__(cls)
Return type: Self
mpi4py.MPI.Cartcomm
class mpi4py.MPI.Cartcomm
Bases: Topocomm
Cartesian topology intracommunicator ๐บ๏ธ bestie this is the one where your processes live on a nice tidy grid, very organized, very demure.
static __new__(cls, comm=None)
Parameters:
- comm (
Cartcomm|None)
Return type: Self
โจ Methods Summary โจ
okay bestie, here's the whole roster of what you can do with your cartesian communicator, no cap:
Get_cart_rank(coords)โ translate logical coordinates into ranks. glow-up from position to process ID ๐Get_coords(rank)โ the reverse, translating ranks back into logical coordinatesGet_dim()โ hand you the number of dimensionsGet_topo()โ spill all the info about the cartesian topologyShift(direction, disp)โ give you the process ranks you need for data shifting withSendrecv<#mpi4py.MPI.Comm.Sendrecv>Sub(remain_dims)โ produce a lower-dimensional Cartesian topology. shrinking but make it iconic ๐ฆ
๐ Attributes Summary ๐
coordsโ Coordinates.dimโ Number of dimensions.dimsโ Dimensions.ndimโ Number of dimensions.periodsโ Periodicity.topoโ Topology information.
๐ Methods Documentation ๐
Get_cart_rank(coords)
Translate logical coordinates to ranks. literally the coordinates-to-rank translator of your dreams โจ
Parameters
- coords (
Sequence[int])
Return type
int
Get_coords(rank)
Translate ranks to logical coordinates. going the other way, equally slay ๐
Parameters
- rank (
int)
Return type
list[int]
Get_dim()
Return number of dimensions.
Return type
int
Get_topo()
Return information on the cartesian topology.
Return type
tuple[list[int], list[int], list[int]]
Shift(direction, disp)
Return a process ranks for data shifting with Sendrecv <#mpi4py.MPI.Comm.Sendrecv>.
Parameters
- direction (
int) - disp (
int)
Return type
tuple[int, int]
Sub(remain_dims)
Return a lower-dimensional Cartesian topology.
Parameters
- remain_dims (
Sequence[bool])
Return type
Cartcomm <#mpi4py.MPI.Cartcomm>
๐ซ Attributes Documentation ๐ซ
coords
Coordinates.
dim
Number of dimensions.
dims
Dimensions.
ndim
Number of dimensions.
periods
Periodicity.
topo
Topology information.
๐ mpi4py.MPI.Comm ๐
class mpi4py.MPI.Comm
Bases: object <https://docs.python.org/3/library/functions.html#object>
Communication context. yeah, this is the moment, this is the main character ๐
static __new__(cls, comm=None)
Parameters
- comm (
Comm<#mpi4py.MPI.Comm> |None<https://docs.python.org/3/library/constants.html#None>)
Return type
Self <https://docs.python.org/3/library/typing.html#typing.Self>
Abort([errorcode])โ Terminate the MPI execution environment. ๐ญ like, the whole thing. everyone out. pass anerrorcodeif you want to be specific about why you're nuking it from orbit ๐Ack_failed([num_to_ack])โ Acknowledge failures on a communicator.</p> you're basically signing off on the mess ๐num_to_acktells it how many failures you're acknowledging.Agree(flag)โ Blocking agreement. everybody has to agree, and nobody moves until they do ๐ซถ theflagis your vote.Allgather(sendbuf, recvbuf)โ Gather to All. everyone sends, everyone receives the whole set. no secrets on this comm, bestie โจAllgather_init(sendbuf, recvbuf[, info])โ Persistent Gather to All. same energy asAllgather, but it sticks around so you can fire it off again and again ๐ฅ optionalinfofor extra intel.Allgatherv(sendbuf, recvbuf)โ Gather to All Vector. the vector version โ because sometimes everyone's bringing a different amount of stuff to the party ๐Allgatherv_init(sendbuf, recvbuf[, info])โ Persistent Gather to All Vector. vector edition, but persistent.infois optional, as always ๐Allreduce(sendbuf, recvbuf[, op])โ Reduce to All. crunch everyone's numbers down and hand the result to literally everyone ๐ drop anopin there to pick your reduction.Allreduce_init(sendbuf, recvbuf[, op, info])โ Persistent Reduce to All.</persistent> persistent flavor โopandinfoare both optional here, fancy ๐Alltoall(sendbuf, recvbuf)โ All to All Scatter/Gather. everyone trades with everyone. it's giving group project where everyone actually participates for once ๐Alltoall_init(sendbuf, recvbuf[, info])โ Persistent All to All Scatter/Gather. same swap, but persistent so you can rerun it.infooptional โจAlltoallv(sendbuf, recvbuf)โ All to All Scatter/Gather Vector. the vector version โ unequal amounts welcome, no judgement ๐ฆAlltoallv_init(sendbuf, recvbuf[, info])โ Persistent All to All Scatter/Gather Vector. vector + persistent = the combo meal ๐infooptional.Alltoallw(sendbuf, recvbuf)โ All to All Scatter/Gather General. the general one. maximum flexibility, maximum power, main character energy fr fr ๐Alltoallw_init(sendbuf, recvbuf[, info])โ Persistent All to All Scatter/Gather General. general AND persistent. and yes,infois optional ๐Attach_buffer(buf)โ Attach a user-provided buffer for sending in buffered mode. you hand itbuf, it uses it. that's the whole vibe ๐ซถBarrier()โ Barrier synchronization. everyone waits at the line until everyone's there. no cuts, no stragglers โญBarrier_init([info])โ Persistent Barrier. the barrier you can reuse.infooptional, obviously ๐Bcast(buf[, root])โ Broadcast data from one process to all other processes. one source, everybody else listening.rootsays who's holding the mic ๐คBcast_init(buf[, root, info])โ Persistent Broadcast. the persistent remix โrootandinfoboth optional โจBsend(buf, dest[, tag])โ Blocking send in buffered mode. buffered mode means it can return before the receiver is ready.destis where it's headed,tagoptional ๐Bsend_init(buf, dest[, tag])โ Persistent request for a send in buffered mode. same buffered send, but you get a persistent request back.destrequired,tagoptional ๐Call_errhandler(errorcode)โ Call the error handler installed on a communicator. you pass theerrorcode, it invokes whatever handler is on deck ๐ญClone()โ Clone an existing communicator. copy-paste but make it MPI. no args, no drama ๐ฆCompare(comm)โ Compare two communicators. you give it acomm, it tells you how they relate. iconique ๐Create(group)โ Create communicator from group. hand it agroup, get a communicator back. slay โจCreate_errhandler(errhandler_fn)โ Create a new error handler for communicators. pass yourerrhandler_fnand boom, custom error handling ๐Create_keyval([copy_fn, delete_fn, nopython])โ Create a new attribute key for communicators. all three args are optional:copy_fn,delete_fn, andnopython๐Delete_attr(keyval)โ Delete attribute value associated with a key. give it thekeyvaland that attribute is gone ๐ซถDetach_buffer()โ Remove an existing attached buffer. the undo button forAttach_buffer. no args needed ๐Disconnect()โ Disconnect from a communicator. you and this communicator? it's over. no cap, it's just over ๐Dup([info])โ Duplicate a communicator. ๐ซDup_with_info(info)โ Duplicate a communicator with hints, bestie. โจFlush_buffer()โ Block until all buffered messages have been transmitted. it's giving "wait for itโฆ" energy ๐ซถFree()โ Free a communicator.Free_keyval(keyval)โ Free an attribute key for communicators. ๐Gather(sendbuf, recvbuf[, root])โ Gather data to one process from all other processes.Gather_init(sendbuf, recvbuf[, root, info])โ Persistent Gather. ๐Gatherv(sendbuf, recvbuf[, root])โ Gather Vector.Gatherv_init(sendbuf, recvbuf[, root, info])โ Persistent Gather Vector.Get_attr(keyval)โ Retrieve attribute value by key.Get_errhandler()โ Get the error handler for a communicator.Get_failed()โ Extract the group of failed processes. ๐Get_group()โ Access the group associated with a communicator.Get_info()โ Return the current hints for a communicator.Get_name()โ Get the print name for this communicator. ๐Get_parent()โ Return the parent intercommunicator for this process.Get_rank()โ Return the rank of this process in a communicator.Get_size()โ Return the number of processes in a communicator.Get_topology()โ Return the type of topology (if any) associated with a communicator.Iagree(flag)โ Nonblocking agreement.Iallgather(sendbuf, recvbuf)โ Nonblocking Gather to All.Iallgatherv(sendbuf, recvbuf)โ Nonblocking Gather to All Vector.Iallreduce(sendbuf, recvbuf[, op])โ Nonblocking Reduce to All.Ialltoall(sendbuf, recvbuf)โ Nonblocking All to All Scatter/Gather.Ialltoallv(sendbuf, recvbuf)โ Nonblocking All to All Scatter/Gather Vector.Ialltoallw(sendbuf, recvbuf)โ Nonblocking All to All Scatter/Gather General.Ibarrier()โ Nonblocking Barrier.Ibcast(buf[, root])โ Nonblocking Broadcast. ๐ฃIbsend(buf, dest[, tag])โ Nonblocking send in buffered mode.Idup([info])โ Nonblocking duplicate a communicator.Idup_with_info(info)โ Nonblocking duplicate a communicator with hints.
okay but notice how every single one of these that starts with a capital I is just the nonblocking version of its non-I bestie?? it's giving "same girl, different era" energy fr fr ๐
the I prefix literally just means "you get a request object back and you go live your life, we'll handle the waiting later" โ no cap. ๐ฆ
okay we're still deep in the communicator method lineup, alphabetically slaying, no skips, keep up bestie ๐
Iflush_buffer()โ nonblocking flush for buffered messages. โจIgather(sendbuf, recvbuf[, root])โ nonblocking Gather.Igatherv(sendbuf, recvbuf[, root])โ nonblocking Gather Vector. the v stands for very extra ๐Improbe([source, tag, status])โ nonblocking test for a matched message. matched specifically, okay? iykyk.Iprobe([source, tag, status])โ nonblocking test for a message. just any message fr fr.Irecv(buf[, source, tag])โ nonblocking receive. she's not gonna wait around for you ๐ซถIreduce(sendbuf, recvbuf[, op, root])โ nonblocking Reduce to Root.Ireduce_scatter(sendbuf, recvbuf[, ...])โ nonblocking Reduce-Scatter, the vector version.Ireduce_scatter_block(sendbuf, recvbuf[, op])โ nonblocking Reduce-Scatter Block, and to be clear that's the regular, non-vector version. two different girls, don't confuse them ๐Irsend(buf, dest[, tag])โ nonblocking send in ready mode. she assumes you're ready, do not disappoint her.Is_inter()โ tells you whether the communicator is an intercommunicator.Is_intra()โ tells you whether the communicator is an intracommunicator. yes bestie, they're different, that's the whole point.Is_revoked()โ indicates whether the communicator has been revoked. ๐ญIscatter(sendbuf, recvbuf[, root])โ nonblocking Scatter.Iscatterv(sendbuf, recvbuf[, root])โ nonblocking Scatter Vector.Isend(buf, dest[, tag])โ nonblocking send. iconic, the moment, no notes ๐Isendrecv(sendbuf, dest[, sendtag, recvbuf, ...])โ nonblocking send and receive. doing both at once, multitasking queen ๐Isendrecv_replace(buf, dest[, sendtag, ...])โ send and receive a message, with the replace twist.Ishrink()โ nonblocking shrink of a communicator, removing all failed processes.Issend(buf, dest[, tag])โ nonblocking send in synchronous mode. the s is doing so much work.Join(fd)โ interconnects two processes that are connected by a socket. ๐ฆMprobe([source, tag, status])โ blocking test for a matched message. yeah, blocking โ she will sit there and wait, respectfully.Precv_init(buf, partitions[, source, tag, info])โ creates a request for a partitioned recv operation.Probe([source, tag, status])โ blocking test for a message.Psend_init(buf, partitions, dest[, tag, info])โ creates a request for a partitioned send operation.Recv(buf[, source, tag, status])โ blocking receive. she waits. patiently. for you. ๐ฅบRecv_init(buf[, source, tag])โ creates a persistent request for a receive. it's giving commitment ๐Reduce(sendbuf, recvbuf[, op, root])โ Reduce to Root.Reduce_init(sendbuf, recvbuf[, op, root, info])โ persistent Reduce to Root. she's back and she's forever.
and we're still not done, the list keeps going, stay with me ๐
Reduce_scatter(sendbuf, recvbuf[, ...])โ Reduce-Scatter, but make it fancy โ this is the vector version. ๐ฆReduce_scatter_block(sendbuf, recvbuf[, op])โ Reduce-Scatter Block, the regular non-vector one. No frills, just vibes. โจReduce_scatter_block_init(sendbuf, recvbuf)โ Persistent Reduce-Scatter Block (again: regular, non-vector, we keep it simple bestie). ๐Reduce_scatter_init(sendbuf, recvbuf[, ...])โ Persistent Reduce-Scatter, and yeah it's the vector flavor. ๐Revoke()โ Revoke a communicator. It's giving "you're on time out". ๐Rsend(buf, dest[, tag])โ Blocking send, but in ready mode. ๐โ๏ธRsend_init(buf, dest[, tag])โ A persistent request for a send in ready mode. Set it once, reuse it forever, iconic behavior. ๐Scatter(sendbuf, recvbuf[, root])โ Scatter data from one process out to all the other processes. Sharing is caring fr fr. ๐ธScatter_init(sendbuf, recvbuf[, root, info])โ Persistent Scatter. Same energy, reusable wrapper. ๐Scatterv(sendbuf, recvbuf[, root])โ Scatter Vector. Vector edition, obviously. ๐Scatterv_init(sendbuf, recvbuf[, root, info])โ Persistent Scatter Vector. Yeah bestie, the vector one but persistent. โจSend(buf, dest[, tag])โ Blocking send. Classic. The blueprint. ๐Send_init(buf, dest[, tag])โ Creates a persistent request for a standard send. ๐Sendrecv(sendbuf, dest[, sendtag, recvbuf, ...])โ Send AND receive a message. Doing both at once is such main character energy. ๐Sendrecv_replace(buf, dest[, sendtag, ...])โ Send and receive a message โ the replace edition. ๐Set_attr(keyval, attrval)โ Stores an attribute value that's associated with a key. ๐๏ธSet_errhandler(errhandler)โ Sets the error handler for a communicator. So when things go sideways, you already decided how it's handled. ๐ญSet_info(info)โ Sets new values for the hints associated with a communicator. ๐งSet_name(name)โ Sets the print name for this communicator. Naming things is self care. ๐Shrink()โ Shrinks a communicator to remove all the failed processes. Cleaning house, no cap. ๐งนSplit([color, key])โ Splits a communicator by color and key. ๐Split_type(split_type[, key, info])โ Splits a communicator by split type. ๐ฆSsend(buf, dest[, tag])โ Blocking send, but in synchronous mode. ๐คSsend_init(buf, dest[, tag])โ Persistent request for a send in synchronous mode. ๐allgather(sendobj)โ Gather to All. Everybody gets everything, we love an equal distribution moment. ๐ธallreduce(sendobj[, op])โ Reduce to All. ๐alltoall(sendobj)โ All to All Scatter/Gather. The chaotic group chat of collectives, honestly. ๐barrier()โ Barrier synchronization. Everyone waits here until everyone's ready โ literally the group chat "ok are we all here?" ๐งbcast(obj[, root])โ Broadcast. One to everyone, no side conversations. ๐ขbsend(obj, dest[, tag])โ Send in buffered mode. ๐งบf2py(arg)โ no description given, she's mysterious like that. ๐free()โ Calls Free if it's not null or predefined. โจ
fromhandle(handle)โ Create object from MPI handle. ๐ซถfromint(arg, /)โ Translate integer handle to object.gather(sendobj[, root])โ Gather.ibsend(obj, dest[, tag])โ Nonblocking send in buffered mode.improbe([source, tag, status])โ Nonblocking test for a matched message.iprobe([source, tag, status])โ Nonblocking test for a message.irecv([buf, source, tag])โ Nonblocking receive.isend(obj, dest[, tag])โ Nonblocking send.issend(obj, dest[, tag])โ Nonblocking send in synchronous mode.mprobe([source, tag, status])โ Blocking test for a matched message.probe([source, tag, status])โ Blocking test for a message.py2f()โ (no description, she's mysterious like that ๐ )recv([buf, source, tag, status])โ Receive.reduce(sendobj[, op, root])โ Reduce to Root.scatter(sendobj[, root])โ Scatter.send(obj, dest[, tag])โ Send in standard mode.sendrecv(sendobj, dest[, sendtag, recvbuf, ...])โ Send and Receive.ssend(obj, dest[, tag])โ Send in synchronous mode.toint()โ Translate object to integer handle.
โจ Attributes Summary โจ
okay bestie, these are the lil vibes you can just read off a communicator, no method call needed ๐
groupโ Group.handleโ MPI handle.infoโ Info hints.is_interโ Is intercommunicator.is_intraโ Is intracommunicator.is_topoโ Is a topology.nameโ Print name.rankโ Rank of this process.sizeโ Number of processes.topologyโ Topology type.
๐ Methods Documentation ๐
okay so now we get into the actual receipts, method by method. grab a snack, this is the good part ๐
Abort(errorcode=0)
Terminate the MPI execution environment. ๐ญ like, it's over over.
Warning: The invocation of this method prevents the execution of various Python exit and cleanup mechanisms. Use this method as a last resort to prevent parallel deadlocks in case of unrecoverable errors. fr fr, this is the nuclear option โ only reach for it when everything else is giving deadlock energy ๐
Parameters
- errorcode (
int)
Return type
NoReturn
Ack_failed(num_to_ack=None)
Acknowledge failures on a communicator.
Parameters
- num_to_ack (
int|None)
Return type
int
Agree(flag)
Blocking agreement. everyone has to agree before we move on, it's giving group project but make it โจsynchronizedโจ
Parameters
- flag (
int)
Return type
int
Allgather(sendbuf, recvbuf)
Gather to All. ๐
Gather data from all processes and broadcast the combined data to all other processes. literally everyone gets everybody's tea, no FOMO allowed ๐ซถ
Parameters
- sendbuf (
BufSpec|InPlace) - recvbuf (
BufSpecB)
Return type
None
Allgather_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent Gather to All.
Parameters
- sendbuf (
BufSpec|InPlace) - recvbuf (
BufSpecB) - info (
Info)
Return type
Prequest
Allgatherv(sendbuf, recvbuf)
Gather to All Vector.
and that's where we're leaving it for now bestie, more incoming ๐
Gathers data from every process and sends it back out to all the other processes โ but here's the โจspicyโจ part: each one can contribute a different amount of data and sit at a different displacement. Not all equal-sized chunks, bestie. Everyone brings their own lil' pile. ๐
Parameters
sendbuf(BufSpec|InPlace) ๐ซถrecvbuf(BufSpecV) ๐ธ
Return type โ None
Allgatherv_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent Gather to All Vector. ๐ฆ Same energy as Allgatherv, but it hands you back a persistent request instead of doing the thing right away. Set it up once, then fire it off whenever. Obsessed.
Parameters
sendbuf(BufSpec|InPlace)recvbuf(BufSpecV)info(Info)
Return type โ Prequest ๐
Allreduce(sendbuf, recvbuf, op=SUM)
Reduce to All. ๐ฅ Everyone smashes their data together with op, and then everyone gets the answer. No one's left out, no main character hogging the result. Iconic behaviour fr fr.
Parameters
sendbuf(BufSpec|InPlace)recvbuf(BufSpec)op(Op)
Return type โ None
Allreduce_init(sendbuf, recvbuf, op=SUM, info=INFO_NULL)
Persistent Reduce to All. โจ The persistent-request version of Allreduce โ set it up, get a Prequest, reuse it forever. So efficient. We love a repeat performer. ๐
Parameters
sendbuf(BufSpec|InPlace)recvbuf(BufSpec)op(Op)info(Info)
Return type โ Prequest ๐
Alltoall(sendbuf, recvbuf)
All to All Scatter/Gather. ๐ Send data to all processes and recv data from all processes โ like a group chat where literally everyone is @-ing everyone. The full send-and-receive glow-up.
Parameters
sendbuf(BufSpecB|InPlace)recvbuf(BufSpecB)
Return type โ None
Alltoall_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent All to All Scatter/Gather. ๐ซ All the all-to-all energy, but persistent. Build the request once, vibe forever.
Parameters
sendbuf(BufSpecB|InPlace)recvbuf(BufSpecB)info(Info)
Return type โ Prequest ๐ฆ
Alltoallv(sendbuf, recvbuf)
All to All Scatter/Gather Vector. ๐ Send data to all processes and recv data from all processes โ and yes, everyone gets to specify different amounts of data and different displacements. No more pretending we're all the same size. Body positivity for buffers. ๐
Parameters
sendbuf(BufSpecV|InPlace)recvbuf(BufSpecV)
Return type โ None
Alltoallv_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent All to All Scatter/Gather Vector. โจ The vector all-to-all, but make it persistent. A Prequest you can keep in your pocket. ๐ซถ
Parameters
sendbuf(BufSpecV|InPlace)recvbuf(BufSpecV)info(Info)
Return type โ Prequest
Alltoallw(sendbuf, recvbuf)
All to All Scatter/Gather General. ๐ Send/recv data to/from all processes, and this one lets you specify different counts, displacements, and datatypes for every single dest/source. Maximum customisation, zero compromises. It's giving "I designed my own outfit for every party". ๐
Parameters
sendbuf(BufSpecW|InPlace)recvbuf(BufSpecW)
Return type โ None
Alltoallw_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent All to All Scatter/Gather General. ๐ Same fully-customisable general all-to-all, now in a persistent-request flavour. Chef's kiss. ๐ญ
Parameters
sendbuf(BufSpecW|InPlace)recvbuf(BufSpecW)info(Info)
Return type โ Prequest โญ
Attach_buffer(buf)
Attach a user-provided buffer for sending in buffered mode. ๐งบ You're handing MPI your own lil' basket so buffered sends have somewhere to stash things. Very demure, very mindful, very prepared. ๐
Parameters
buf(Buffer|None)
Return type โ None
Barrier()
Barrier synchronization. โณ The classic "okay everyone STOP and wait until we're all here" moment. Nobody moves until the whole squad arrives. It's the group photo pose. ๐ธ
Return type โ None
Barrier_init(info=INFO_NULL)
Persistent Barrier. ๐ฆ A barrier that you set up once and can reuse โ no re-declaring, just vibes.
Parameters
info(Info)
Return type โ Prequest ๐
Bcast(buf, root=0)
Broadcast data from one process to all other processes. ๐ฃ One process gets the mic, everyone else listens and copies it down. root decides who's holding the aux. Default root is 0, so the usual suspect. ๐ค
Parameters
buf(BufSpec)root(int)
Return type โ None
Bcast_init(buf, root=0, info=INFO_NULL)
Persistent Broadcast. โจ Broadcast, but persistent โ get your Prequest, reuse it on repeat. A hit single, basically. ๐ถ
Parameters
buf(BufSpec)root(int)info(Info)
Return type โ Prequest
Bsend(buf, dest, tag=0)
Blocking send in buffered mode. ๐ฆ It sends, it blocks, and it uses that buffered-mode setup you attached earlier. dest is who's getting it, tag is the lil' label (defaults to 0). ๐ท๏ธ
Parameters
buf(BufSpec)dest(int)tag(int)
Return type โ None
Bsend_init(buf, dest, tag=0)
Persistent request for a send in buffered mode. ๐ซถ The buffered send, but persistent โ and this one hands you a Request (not a Prequest, bestie, watch the type ๐).
Parameters
buf(BufSpec)dest(int)tag(int)
Return type โ Request ๐
Call_errhandler(errorcode)
Call the error handler installed on a communicator. ๐จ You're poking the handler that's currently attached to this communicator and telling it "hey, here's the errorcode, deal with it". Dramatic, but sometimes necessary. ๐ญ
Parameters
errorcode(int)
Return type โ None
Clone()
Clone an existing communicator. ๐ฏ A copy of the communicator โ same energy, whole new object. Dupe, but make it official.
Return type โ Self ๐
Compare(comm)
Compare two communicators. ๐ Ask it how this communicator stacks up against comm and it hands you back an int telling you the deal.
Parameters
comm(Comm)
Return type โ int
Create(group)
Create communicator from group. ๐ ๏ธ Feed it a Group and it'll spin you up a fresh Comm. Build-a-bear, but for communicators.
Parameters
group(Group)
Return type โ Comm โจ
classmethod Create_errhandler(errhandler_fn)
Create a new error handler for communicators. ๐จโจ Give it a callable and it makes you a brand-new Errhandler. The callable takes a Comm and an int, and returns None โ that's the whole contract, no cap.
Parameters
errhandler_fn(Callable[[Comm, int], None])
Return type โ Errhandler ๐
classmethod Create_keyval(copy_fn=None, delete_fn=None, nopython=False)
Create a new attribute key for communicators. ๐๏ธ You're minting a brand-new attribute key so you can stash extra stuff on communicators. Both callback slots default to None, and nopython defaults to False. Very custom, very yours.
Parameters
copy_fn(Callable[[Comm, int, Any], Any]|None) ๐ฆdelete_fn(Callable[[Comm, int, Any], None] | None) โ the callback that fires when an attribute gets deletednopython(bool) โ whether to skip Python-level callback dispatch
Return type: int
Delete_attr(keyval)</p> ๐๏ธ
okay so this one deletes the attribute value that's chilling with a particular key. bye bestie ๐
Parameters
keyval(int) โ the key whose attribute you're yeeting
Return type: None
Detach_buffer()</p> ๐ฆ
Removes a buffer that was already attached. Un-glues it. simple as that.
Return type: Buffer | None
Disconnect()</p> ๐
Disconnect from a communicator. it's giving "we need to talk" energy but for comms.
Return type: None
Dup(info=None)</p> ๐ฏ
Duplicate a communicator. one comm becomes two, iconic behaviour, no notes.
Parameters
info(Info | None) โ hints for the new copy, or nothing at all
Return type: Self
Dup_with_info(info)</p> ๐ฏโโ๏ธโจ
Duplicate a communicator with hints. same dupe energy, but you're feeding it info for real this time.
Parameters
info(Info) โ the hints, and this time they're not optional
Return type: Self
Flush_buffer()</p> ๐ฝ๐จ
Block until every buffered message has actually been transmitted. like, sit there and wait, bestie, the messages are still in transit ๐ซถ
Return type: None
Free()</p> ๐๏ธ
Free a communicator. release it into the wild.
Return type: None
classmethod Free_keyval(keyval)</p> ๐
Free an attribute key for communicators. it's a classmethod, so you call it on the class itself, not on an instance. iykyk.
Parameters
keyval(int) โ the key you're freeing
Return type: int
Gather(sendbuf, recvbuf, root=0)</p> ๐งบ
Gather data to one process from all the other processes. everyone hands their stuff to root, root holds the whole pile. main character root energy fr fr ๐
Parameters
sendbuf(BufSpec | InPlace) โ what you're sendingrecvbuf(BufSpecB | None) โ where it all lands (only meaningful onroot)root(int) โ the process collecting everything, defaults to0
Return type: None
Gather_init(sendbuf, recvbuf, root=0, info=INFO_NULL)</p> ๐งบโจ
Persistent Gather. same gathering vibe, but you set it up once and reuse it. lowkey efficient.
Parameters
sendbuf(BufSpec | InPlace) โ what you're sendingrecvbuf(BufSpecB | None) โ where it landsroot(int) โ the collector, defaults to0info(Info) โ hints, defaults toINFO_NULL
Return type: Prequest
Gatherv(sendbuf, recvbuf, root=0)</p> ๐งบ๐
Gather Vector. Gather data to one process from all the other processes โ except everyone can send different amounts of data, at different displacements. no uniformity required, we love range ๐
Parameters
sendbuf(BufSpec | InPlace) โ what you're sendingrecvbuf(BufSpecV | None) โ where it lands, vector-styleroot(int) โ the collector, defaults to0
Return type: None
Gatherv_init(sendbuf, recvbuf, root=0, info=INFO_NULL)</p> ๐งบ๐โจ
Persistent Gather Vector. yes it's the persistent version of Gatherv, and yes it still does the different-amounts-different-displacements thing.
Parameters
sendbuf(BufSpec | InPlace) โ what you're sendingrecvbuf(BufSpecV | None) โ where it landsroot(int) โ the collector, defaults to0info(Info) โ hints, defaults toINFO_NULL
Return type: Prequest
Get_attr(keyval)</p> ๐
Retrieve an attribute value by key. the reverse of Delete_attr, if you will.
Parameters
keyval(int) โ the key you're looking up
Return type: int | Any | None
Get_errhandler()</p> ๐จ
Get the error handler for a communicator. who's on aux when things go wrong.
Return type: Errhandler
Get_failed()</p> ๐
Extract the group of failed processes. yeah. the ones that did not make it.
Return type: Group
Get_group()</p> ๐ฅ
Access the group associated with a communicator. the whole squad, in group form.
Return type: Group
Get_info()</p> ๐
Return the current hints for a communicator. receipts on what you told it.
Return type: Info
Get_name()</p> ๐ท๏ธ
Get the print name for this communicator. its little nickname for display purposes.
Return type: str
classmethod Get_parent()</p> ๐จโ๐ฉโ๐ง
Return the parent intercommunicator for this process. it's a classmethod, so call it on the class. family reunion vibes.
Return type: Intercomm
Get_rank()</p> ๐ข
Return the rank of this process in a communicator. who am i. classic.
Return type: int
Get_size()</p> ๐ขโจ
Return the number of processes in a communicator. how many of us are in the group chat.
Return type: int
Get_topology()</p> ๐บ๏ธ
Return the type of topology (if any) associated with a communicator. if there's no topology, that's also an answer, bestie.
Return type: int
Iagree(flag)</p> ๐ค
Nonblocking agreement. the I prefix means you get a Request back instead of just waiting around. very on the go.
Parameters
flag(Buffer) โ the buffer for the agreement flag
Return type: Request
Iallgather(sendbuf, recvbuf)</p> ๐ฃ
Nonblocking Gather to All. everyone sends, everyone receives. equal-opportunity communication ๐
Parameters
sendbuf(BufSpec | InPlace) โ what you're sendingrecvbuf(BufSpecB) โ where it lands
Return type: Request
Iallgatherv(sendbuf, recvbuf)</p> ๐ฃ๐
Nonblocking Gather to All Vector. same as above but with the vector flavour โ different counts, different displacements.
Parameters
sendbuf(BufSpec | InPlace) โ what you're sendingrecvbuf(BufSpecV) โ where it lands
Return type: Request
Iallreduce(sendbuf, recvbuf, op=SUM)</p> โโจ
Nonblocking Reduce to All. everyone contributes, everyone gets the combined result. collective slay.
Parameters
sendbuf(BufSpec | InPlace) โ what you're contributingrecvbuf(BufSpec) โ where the result landsop(Op) โ the reduction operation, defaults toSUM
Return type: Request
Ialltoall(sendbuf, recvbuf)</p> ๐
Nonblocking All to All Scatter/Gather. literally everyone trades with everyone. chaotic? maybe. iconic? absolutely.
Parameters
sendbuf(BufSpecB | InPlace) โ what you're sendingrecvbuf(BufSpecB) โ what you're receiving
Return type: Request
Ialltoallv(sendbuf, recvbuf)</p> ๐๐
Nonblocking All to All Scatter/Gather Vector. the vector version โ so the amounts and displacements can differ per partner.
Parameters
sendbuf(BufSpecV | InPlace) โ what you're sendingrecvbuf(BufSpecV) โ what you're receiving
Return type: Request
Ialltoallw(sendbuf, recvbuf)</p> ๐๐
Nonblocking All to All Scatter/Gather General. the general one. the most unhinged (affectionate) of the all-to-all family.
Parameters
sendbuf(BufSpecW | InPlace) โ the thing you're sending, or the in-place flex if you're skipping the separate send buffer ๐ซถrecvbuf(BufSpecW) โ where the goods land
Return type: Request
Ibarrier()
Nonblocking Barrier. Nobody moves till everybody's here, but make it async so you're not just standing there ๐
Return type: Request
Ibcast(buf, root=0)
Nonblocking Broadcast. One root yaps, everyone else receives the tea โจ
Parameters
buf(BufSpec) โ the buffer getting broadcastroot(int) โ who's the source of truth here
Return type: Request
Ibsend(buf, dest, tag=0)
Nonblocking send, but in buffered mode ๐งบ โ the message gets stashed locally so the send can finish without the receiver already waiting.
Parameters
buf(BufSpec) โ what you're sendingdest(int) โ who gets ittag(int) โ the little label that keeps your messages straight
Return type: Request
Idup(info=None)
Nonblocking duplicate a communicator ๐ฏ โ clone the whole vibe, no blocking.
Parameters
info(Info | None) โ optional hints to hand over
Return type: tuple[Self, Request] โ the new communicator and the request you gotta babysit, bestie
Idup_with_info(info)
Nonblocking duplicate a communicator with hints ๐ โ same clone energy, but you're required to pass the hints, no skipping.
Parameters
info(Info) โ the hints, mandatory this time
Return type: tuple[Self, Request]
Iflush_buffer()
Nonblocking flush for buffered messages ๐ฝโจ โ kicks out everything you shoved into the buffer with Bsend, asynchronously.
Return type: Request
Igather(sendbuf, recvbuf, root=0)
Nonblocking Gather โ everybody sends their piece to the root, but nobody waits around for it ๐ธ
Parameters
sendbuf(BufSpec | InPlace) โ your contributionrecvbuf(BufSpecB | None) โ where the pile lands (root's business, soNoneelsewhere)root(int) โ the one collecting everything
Return type: Request
Igatherv(sendbuf, recvbuf, root=0)
Nonblocking Gather Vector โ like gather, except everyone's allowed to bring a different amount ๐. Nobody has to match.
Parameters
sendbuf(BufSpec | InPlace) โ your piece, whatever size it isrecvbuf(BufSpecV | None) โ the uneven pile at the rootroot(int) โ the collector
Return type: Request
Improbe(source=ANY_SOURCE, tag=ANY_TAG, status=None)
Nonblocking test for a matched message ๐ โ peeks and, if there's something there, actually matches it and hands you the Message.
Parameters
source(int) โ who you're checking ontag(int) โ which tag you're checking forstatus(Status | None) โ where to stash the status info
Return type: Message | None โ a message if there is one, None if there isn't ๐ญ
Iprobe(source=ANY_SOURCE, tag=ANY_TAG, status=None)
Nonblocking test for a message ๐ โ just checks if one's waiting, doesn't consume it.
Parameters
source(int) โ the sender you're side-eyeingtag(int) โ the tag you're side-eyeingstatus(Status | None) โ optional status receptacle
Return type: bool
Irecv(buf, source=ANY_SOURCE, tag=ANY_TAG)
Nonblocking receive ๐ฅ โ you set it up, get a Request back, and go live your life until it's ready.
Parameters
buf(BufSpec) โ where the incoming thing goessource(int) โ who you're expectingtag(int) โ which tag you're expecting
Return type: Request
Ireduce(sendbuf, recvbuf, op=SUM, root=0)
Nonblocking Reduce to Root ๐ฅ โ everyone combines their stuff into one result, root gets it, nobody blocks.
Parameters
sendbuf(BufSpec | InPlace) โ your inputrecvbuf(BufSpec | None) โ the final answer (root only)op(Op) โ how you're combining, defaults toSUMroot(int) โ who receives the result
Return type: Request
Ireduce_scatter(sendbuf, recvbuf, recvcounts=None, op=SUM)
Nonblocking Reduce-Scatter, vector version ๐ โ reduce everything together, then scatter chunks of varying sizes back out.
Parameters
sendbuf(BufSpec | InPlace) โ your inputrecvbuf(BufSpec) โ your share of the resultrecvcounts(Sequence[int] | None) โ how much each rank gets, uneven welcomeop(Op) โ the reduction operator, defaults toSUM
Return type: Request
Ireduce_scatter_block(sendbuf, recvbuf, op=SUM)
Nonblocking Reduce-Scatter Block โ the regular, non-vector version ๐. Everyone gets the same-sized chunk, no custom counts needed.
Parameters
sendbuf(BufSpecB | InPlace) โ your inputrecvbuf(BufSpec | BufSpecB) โ your equal-sized sliceop(Op) โ the operator, defaults toSUM
Return type: Request
Irsend(buf, dest, tag=0)
Nonblocking send in ready mode โก โ only legal if the matching receive is already posted. Do not play with this one casually, fr fr.
Parameters
buf(BufSpec) โ what's going outdest(int) โ who it's going totag(int) โ the message tag
Return type: Request
Is_inter()
Return whether the communicator is an intercommunicator ๐ฆ โ i.e. it bridges two separate groups.
Return type: bool
Is_intra()
Return whether the communicator is an intracommunicator ๐ธ โ i.e. everyone's in one single group.
Return type: bool
Is_revoked()
Indicate whether the communicator has been revoked ๐ โ you'd wanna know if it was.
Return type: bool
Iscatter(sendbuf, recvbuf, root=0)
Nonblocking Scatter โ root splits the goods and flings them out, async edition ๐
Parameters
sendbuf(BufSpecB | None) โ the pile being split (root's job,Nonefor everyone else)recvbuf(BufSpec | InPlace) โ your incoming shareroot(int) โ the one doing the splitting
Return type: Request
Iscatterv(sendbuf, recvbuf, root=0)
Nonblocking Scatter Vector โ scattering, but each rank gets a different amount ๐. Equal portions are so last season.
Parameters
sendbuf(BufSpecV | None) โ the uneven pile (root only)recvbuf(BufSpec | InPlace) โ your custom-sized shareroot(int) โ the splitter
Return type: Request
Isend(buf, dest, tag=0)
Nonblocking send ๐ค โ the classic. Fire it off, grab your Request, deal with it later.
Parameters
buf(BufSpec) โ what you're sendingdest(int) โ the lucky recipienttag(int) โ the tag, keeping your messages from getting mixed up
Return type: Request
Isendrecv(sendbuf, dest, sendtag=0, recvbuf=None, source=ANY_SOURCE, recvtag=ANY_TAG)
Nonblocking send and receive, in one go ๐ โ no deadlock drama, no awkward waiting, just pure main character energy.
Parameters
sendbuf(BufSpec) โ the thing you're shipping outdestโ (int) ๐ the rank you're aiming atsendtagโ (int) the tag you're stamping on the outgoing messagerecvbufโ (BufSpec|None) where the incoming stuff lands, orNoneif you're not catching anythingsourceโ (int) who you're listening forrecvtagโ (int) the tag you're matching on the way in
Return type: Request
Isendrecv_replace(buf, dest, sendtag=0, source=ANY_SOURCE, recvtag=ANY_TAG)
Okay bestie, this one sends a message and receives one, and the tea is that the same buffer buf is used for both โ send it out, get the replacement back in the same spot. Recycling queen ๐โจ
Note: this function is guaranteed not to deadlock in situations where pairs of blocking sends and receives may deadlock. That's literally the whole point of it existing, no cap.
Caution: a common mistake when using this function is to mismatch the tags with the source and destination ranks, which can result in deadlock. So likeโฆ double-check your tags, bestie, I'm begging ๐๐
Parameters
bufโ (BufSpec) ๐ซถdestโ (int)sendtagโ (int)sourceโ (int)recvtagโ (int)
Return type: Request
Ishrink()
Nonblocking shrink a communicator to remove all failed processes. โ๏ธ bye felicia, you're not in this group chat anymore.
Return type: tuple[Comm, Request] โ yes, a tuple, two things at once, it's giving multitasking ๐
Issend(buf, dest, tag=0)
Nonblocking send in synchronous mode. It's the same vibe as the normal send but โจsynchronousโจ, and nonblocking, so your code keeps moving while it does its thing.
Parameters
bufโ (BufSpec) ๐ธdestโ (int) ๐ฏtagโ (int) ๐ท๏ธ
Return type: Request
classmethod Join(fd)
Interconnect two processes connected by a socket. It's a classmethod, so call it on the class itself, not on an instance. ๐
Parameters
fdโ (int) the file descriptor, literally just a number bestie
Return type: Intercomm
Mprobe(source=ANY_SOURCE, tag=ANY_TAG, status=None)
Blocking test for a matched message. ๐ It sits there and waits (blocks!) until a message that actually matches shows up โ matched, as in the source/tag actually line up. No match, no return.
Parameters
sourceโ (int) ๐tagโ (int)statusโ (Status|None) ๐
Return type: Message
Precv_init(buf, partitions, source=ANY_SOURCE, tag=ANY_TAG, info=INFO_NULL)
Create a request for a partitioned recv operation. Partitioned, as in partitions chunks of the buffer, and you get a Prequest back so you can fire it off whenever. ๐ง
Parameters
bufโ (BufSpec)partitionsโ (int)sourceโ (int)tagโ (int)infoโ (Info)
Return type: Prequest
Probe(source=ANY_SOURCE, tag=ANY_TAG, status=None)
Blocking test for a message. It just tells you if a message is there and gives you the status tea.
Note: this function blocks until the message arrives. So do not call it if you were hoping to do literally anything else in the meantime. ๐ญ
Parameters
sourceโ (int)tagโ (int)statusโ (Status|None)
Return type: Literal[True] โ that's it. True. Iconic, honestly. โ
Psend_init(buf, partitions, dest, tag=0, info=INFO_NULL)
Create a request for a partitioned send operation. Same partitioned energy as Precv_init but going out instead of coming in. ๐
Parameters
bufโ (BufSpec)partitionsโ (int)destโ (int)tagโ (int)infoโ (Info)
Return type: Prequest
Recv(buf, source=ANY_SOURCE, tag=ANY_TAG, status=None)
Blocking receive. Classic. The bread and butter. ๐๐ง
Note: this function blocks until the message is received. It will simply sit there. Patiently. Forever if it has to.
Parameters
bufโ (BufSpec) the landing zone ๐ฌsourceโ (int)tagโ (int)statusโ (Status|None)
Return type: None
Recv_init(buf, source=ANY_SOURCE, tag=ANY_TAG)
Create a persistent request for a receive. Persistent, as in you set it up once and reuse it, which is a whole mood. ๐
Parameters
bufโ (BufSpec)sourceโ (int)tagโ (int)
Return type: Prequest
Reduce(sendbuf, recvbuf, op=SUM, root=0)
Reduce to Root. Everybody's sending their data in and it all gets squished together with op (default SUM, so we're adding ๐
) and the result ends up at rank root.
Parameters
sendbufโ (BufSpec|InPlace)recvbufโ (BufSpec|None)opโ (Op)rootโ (int)
Return type: None
Reduce_init(sendbuf, recvbuf, op=SUM, root=0, info=INFO_NULL)
Persistent Reduce to Root. Same deal as above, but you get a Prequest you can launch over and over. ๐ฆ
Parameters
sendbufโ (BufSpec|InPlace)recvbufโ (BufSpec|None)opโ (Op)rootโ (int)infoโ (Info)
Return type: Prequest
Reduce_scatter(sendbuf, recvbuf, recvcounts=None, op=SUM)
Reduce-Scatter, vector version. Everybody reduces, then the result gets scattered out in uneven little pieces โ recvcounts is how you say who gets how much. ๐๐๐
Parameters
sendbufโ (BufSpec|InPlace)recvbufโ (BufSpec)recvcountsโ (Sequence[int]|None)opโ (Op)
Return type: None
Reduce_scatter_block(sendbuf, recvbuf, op=SUM)
Reduce-Scatter Block โ the regular, non-vector version. No recvcounts list here, everyone just gets the same amount, periodt. ๐
Parameters
sendbufโ (BufSpecB|InPlace)recvbufโ (BufSpec|BufSpecB)opโ (Op)
Return type: None
Reduce_scatter_block_init(sendbuf, recvbuf, op=SUM, info=INFO_NULL)
Persistent Reduce-Scatter Block โ again, the regular, non-vector version, but now you get a reusable Prequest out of it. ๐โจ
Parameters
sendbufโ (BufSpecB|InPlace)recvbufโ (BufSpec|BufSpecB)opโ (Op)infoโ (Info)
Return type: Prequest
Return type: Prequest
๐ซถ Reduce_scatter_init(sendbuf, recvbuf, recvcounts=None, op=SUM, info=INFO_NULL)
Persistent Reduce-Scatter, but make it the vector version โจ (so every rank can get a different amount, no cap).
Parameters
sendbufโBufSpecorInPlacerecvbufโBufSpecrecvcountsโSequence[int]orNoneopโOpinfoโInfo
Return type: Prequest
๐
Revoke()
Revoke a communicator. Yeah bestie, it's exactly what it sounds like ๐ซ
Return type: None
๐ Rsend(buf, dest, tag=0)
Blocking send, but in ready mode ๐ฅ (so the matching receive better already be posted, iykyk).
Parameters
bufโBufSpecdestโinttagโint
Return type: None
๐ง Rsend_init(buf, dest, tag=0)
A persistent request for a send in ready mode. Set it up once, fire it off forever, slay ๐ซ
Parameters
bufโBufSpecdestโinttagโint
Return type: Request
๐ Scatter(sendbuf, recvbuf, root=0)
Scatter data from one process out to all the other processes ๐ฆ one root, everybody gets a piece, we love a distribution moment.
Parameters
sendbufโBufSpecBorNonerecvbufโBufSpecorInPlacerootโint
Return type: None
โญ Scatter_init(sendbuf, recvbuf, root=0, info=INFO_NULL)
Persistent Scatter ๐ set it up one time, then just keep hitting it.
Parameters
sendbufโBufSpecBorNonerecvbufโBufSpecorInPlacerootโintinfoโInfo
Return type: Prequest
๐ Scatterv(sendbuf, recvbuf, root=0)
Scatter Vector ๐ธ
Scatter data from one process to all other processes, except here you get to hand out different amounts of data and displacements โ everyone gets a custom-sized lil gift ๐
Parameters
sendbufโBufSpecVorNonerecvbufโBufSpecorInPlacerootโint
Return type: None
๐ Scatterv_init(sendbuf, recvbuf, root=0, info=INFO_NULL)
Persistent Scatter Vector ๐ the custom-sized-gift version, but make it reusable.
Parameters
sendbufโBufSpecVorNonerecvbufโBufSpecorInPlacerootโintinfoโInfo
Return type: Prequest
๐ Send(buf, dest, tag=0)
Blocking send. The classic. The icon. The moment ๐ซถ
Note: This function may block until the message is received. Whether Send blocks or not depends on several factors and is implementation dependent. So likeโฆ don't build your whole personality around it returning immediately, okay? ๐ญ
Parameters
bufโBufSpecdestโinttagโint
Return type: None
โจ Send_init(buf, dest, tag=0)
Create a persistent request for a standard send ๐
Parameters
bufโBufSpecdestโinttagโint
Return type: Prequest
๐ฆ Sendrecv(sendbuf, dest, sendtag=0, recvbuf=None, source=ANY_SOURCE, recvtag=ANY_TAG, status=None)
Send and receive a message. One call, two jobs, main character energy fr fr ๐ฅ
Note: This function is guaranteed not to deadlock in situations where pairs of blocking sends and receives may deadlock. So it's the safe bestie in a room full of risky ones ๐
Caution: A common mistake when using this function is to mismatch the tags with the source and destination ranks, which can result in deadlock. Do NOT do this. It's giving chaos and not the cute kind ๐
Parameters
sendbufโBufSpecdestโintsendtagโintrecvbufโBufSpecorNonesourceโintrecvtagโintstatusโStatusorNone
Return type: None
๐ซ Sendrecv_replace(buf, dest, sendtag=0, source=ANY_SOURCE, recvtag=ANY_TAG, status=None)
Send and receive a message. Same vibe as above, but the buffer gets replaced in place ๐ธ
Note: This function is guaranteed not to deadlock in situations where pairs of blocking sends and receives may deadlock. Obsessed with the reliability honestly ๐
Caution: A common mistake when using this function is to mismatch the tags with the source and destination ranks, which can result in deadlock. Yeah bestie, same trap, don't fall in it ๐
Parameters
bufโBufSpecdestโintsendtagโintsourceโintrecvtagโintstatusโStatusorNone
Return type: None
๐ Set_attr(keyval, attrval)
Store an attribute value associated with a key ๐๏ธ lil key-value situation, keep it cute.
Parameters
keyvalโintattrvalโAny
Return type: None
๐ Set_errhandler(errhandler)
Set the error handler for a communicator ๐จ decide once and for all how you wanna be told things went wrong.
Parameters
errhandlerโErrhandler
Return type: None
๐ซง Set_info(info)
Set new values for the hints associated with a communicator ๐ญ updating the vibe notes.
Parameters
infoโInfo
Return type: None
๐ Set_name(name)
Set the print name for this communicator ๐ท๏ธ give it a little nickname so it shows up cute in debug output.
Parameters
nameโstr- Return type:
Noneโ yeah, nothing comes back out of this one, and that's the whole vibe ๐ Shrink()โ shrinks a communicator, and by shrink I mean it removes all failed processes so the group can keep it moving. Collective glow-down. ๐ง- Return type:
Comm
- Return type:
Split(color=0, key=0)โ splits the communicator up by color and key. Sorting-hat energy, fr fr. ๐- Parameters:
- color (
int) - key (
int)
- color (
- Return type:
Comm
- Parameters:
Split_type(split_type, key=0, info=INFO_NULL)โ same split energy but this time you're splitting by split type, and you can passInfoalong for the ride. โจ- Parameters:
- split_type (
int) - key (
int) - info (
Info)
- split_type (
- Return type:
Comm
- Parameters:
Ssend(buf, dest, tag=0)โ a blocking send, but make it synchronous mode. It's giving "I'm not done until you've acknowledged me," no cap. ๐ค- Parameters:
- buf (
BufSpec) - dest (
int) - tag (
int)
- buf (
- Return type:
None
- Parameters:
Ssend_init(buf, dest, tag=0)โ a persistent request for a send in synchronous mode. Set it up now, fire it whenever. So organized. ๐- Parameters:
- buf (
BufSpec) - dest (
int) - tag (
int)
- buf (
- Return type:
Request
- Parameters:
allgather(sendobj)โ Gather to All. Everybody gets everybody's stuff. Sharing is caring, bestie. ๐ซถ- Parameters:
- sendobj (
Any)
- sendobj (
- Return type:
list[Any]
- Parameters:
allreduce(sendobj, op=SUM)โ Reduce to All. Everyone does the reduction, everyone gets the answer. The most democratic thing in this whole file. ๐- Parameters:
- sendobj (
Any) - op (
Op|Callable[[Any, Any], Any])
- sendobj (
- Return type:
Any
- Parameters:
alltoall(sendobj)โ All to All Scatter/Gather. Chaotic but make it organized. ๐- Parameters:
- sendobj (
Sequence[Any])
- sendobj (
- Return type:
list[Any]
- Parameters:
barrier()โ Barrier synchronization. Everyone waits right here together, no cutting the line, no exceptions. โ- Note: This method is equivalent to
Barrier. - Return type:
None
- Note: This method is equivalent to
bcast(obj, root=0)โ Broadcast. root yells, everyone hears it. ๐ข- Parameters:
- obj (
Any) - root (
int)
- obj (
- Return type:
Any
- Parameters:
bsend(obj, dest, tag=0)โ send, but in buffered mode. The message chills in a buffer until it's ready to go. ๐- Parameters:
- obj (
Any) - dest (
int) - tag (
int)
- obj (
- Return type:
None
- Parameters:
classmethod f2py(arg)โ it's a classmethod, it takes arg, it hands back aComm. No description given, it's just out here being mysterious. ๐- Parameters:
- arg (
int)
- arg (
- Return type:
Comm
- Parameters:
free()โ callsFreeif it's not null and not predefined. Basically: if you're not nothing and you're not already special, you're free to go, bestie. ๐ฆ- Return type:
None
- Return type:
classmethod fromhandle(handle)โ creates an object from an MPI handle. Full glow-up, handle to object, iconic. โจ- Parameters:
- handle (
int)
- handle (
- Return type:
Comm
- Parameters:
classmethod fromint(arg, /)โ translates an integer handle into an object. Also note that lone/โ arg is positional-only, so don't try to get cute with keywords. ๐- Parameters:
- arg (
int)
- arg (
- Return type:
Comm
- Parameters:
gather(sendobj, root=0)โ Gather. Everything gets pulled in to root, and everyone else just vibes. ๐ฅ- Parameters:
- sendobj (
Any) - root (
int)
- sendobj (
- Return type:
list[Any] | None
- Parameters:
ibsend(obj, dest, tag=0)โ nonblocking send in buffered mode. Same buffered energy, but you don't sit around waiting for it. ๐โโ๏ธ- Parameters:
- obj (
Any) - dest (
int) - tag (
int)
- obj (
- Return type:
Request
- Parameters:
improbe(source=ANY_SOURCE, tag=ANY_TAG, status=None)โ nonblocking test for a matched message. Peeking to see if your message has arrived and is ready to be matched up. ๐- Parameters:
- source (
int) - tag (
int) - status (
Status|None)
- source (
- Return type:
Message | None
- Parameters:
iprobe(source=ANY_SOURCE, tag=ANY_TAG, status=None)โ nonblocking test for a message. Just checking, not committing. ๐ซฃ- Parameters:
- source (
int) - tag (
int) - status (
Status|None)
- source (
- Return type:
bool
- Parameters:
irecv(buf=None, source=ANY_SOURCE, tag=ANY_TAG)โ nonblocking receive. It comes back with aRequestimmediately and you deal with the rest later. Main character time management. โฐ- Parameters:
- buf (
Buffer|None) - source (
int) - tag (
int)
- buf (
- Return type:
Request
- Parameters:
isend(obj, dest, tag=0)โ nonblocking send. Drop it and keep moving, bestie. ๐จ- Parameters:
- obj (
Any) - dest (
int) - tag (
int)
- obj (
- Return type:
Request
- Parameters:
issend(obj, dest, tag=0)โ nonblocking send in synchronous mode. Both at once, obsessed with the range. ๐- Parameters:
- obj (
Any) - dest (
int) - tag (
int)
- obj (
- Return type:
Request
- Parameters:
mprobe(source=ANY_SOURCE, tag=ANY_TAG, status=None)โ blocking test for a matched message. ๐
So like, probe is the vibe-check version, but mprobe is the full matched message tea. It waits until a matching message actually lands, then hands you the whole thing. no cap.
Parameters
sourceโinttagโintstatusโStatusorNone
Return type: Message
probe(source=ANY_SOURCE, tag=ANY_TAG, status=None)โ blocking test for a message. โจ
It literally just blocks until some message shows up, then tells you yes. It's giving "is anyone there??" energy, bestie.
Parameters
sourceโinttagโintstatusโStatusorNone
Return type: Literal[True]
py2f()โ no description in the original, it's just out here doing its thing. ๐ฆ
Return type: int
recv(buf=None, source=ANY_SOURCE, tag=ANY_TAG, status=None)โ receive. ๐ฅ
The main character of message-passing ngl. You get a message, you get an answer, slay.
Parameters
bufโBufferorNonesourceโinttagโintstatusโStatusorNone
Return type: Any
reduce(sendobj, op=SUM, root=0)โ reduce to root. ๐
Everyone sends their little contribution, everything gets smooshed together with op, and the result goes to the root. Iconic group-project behaviour, except this one actually works.
Parameters
sendobjโAnyopโOporCallable[[Any, Any], Any]rootโint
Return type: Any or None
scatter(sendobj, root=0)โ scatter. ๐
The reverse of gather, fr fr. One big chunk gets split up and yeeted out to everyone from the root.
Parameters
sendobjโSequence[Any]orNonerootโint
Return type: Any
send(obj, dest, tag=0)โ send in standard mode. ๐
Parameters
objโAnydestโinttagโint
Return type: None
sendrecv(sendobj, dest, sendtag=0, recvbuf=None, source=ANY_SOURCE, recvtag=ANY_TAG, status=None)โ send and receive. ๐ฅ
Sending and receiving at the same time?? multitasking queen behaviour, honestly.
Parameters
sendobjโAnydestโintsendtagโintrecvbufโBufferorNonesourceโintrecvtagโintstatusโStatusorNone
Return type: Any
ssend(obj, dest, tag=0)โ send in synchronous mode. โณ
Parameters
objโAnydestโinttagโint
Return type: None
toint()โ translate object to integer handle. ๐ข
Return type: int
๐ Attributes Documentation ๐
groupโ Group.handleโ MPI handle.infoโ Info hints.is_interโ is intercommunicator.is_intraโ is intracommunicator.is_topoโ is a topology.nameโ print name.rankโ rank of this process.sizeโ number of processes.topologyโ topology type.
๐ฆ mpi4py.MPI.Datatype ๐ฆ
class mpi4py.MPI.Datatype
Bases: object
Datatype object. it's giving very "I am the blueprint" energy ๐
static __new__(cls, datatype=None)
Parameters
datatypeโDatatypeorNone
Return type: Self
โจ Methods Summary โจ
okay bestie, here's the whole menu of Datatype methods, no skips, no cap ๐
Commit()โ commit the datatype. it's giving "yes i'm ready now" ๐ซถCreate_contiguous(count)โ create a contiguous datatype.Create_darray(size, rank, gsizes, distribs, ...)โ create a datatype for a distributed array on Cartesian process grids.Create_f90_complex(p, r)โ return a bounded complex datatype.Create_f90_integer(r)โ return a bounded integer datatype.Create_f90_real(p, r)โ return a bounded real datatype.Create_hindexed(blocklengths, displacements)โ create an indexed datatype.Create_hindexed_block(blocklength, displacements)โ create an indexed datatype with constant-sized blocks.Create_hvector(count, blocklength, stride)โ create a vector (strided) datatype with stride in bytes.Create_indexed(blocklengths, displacements)โ create an indexed datatype.Create_indexed_block(blocklength, displacements)โ create an indexed datatype with constant-sized blocks.Create_keyval([copy_fn, delete_fn, nopython])โ create a new attribute key for datatypes.Create_resized(lb, extent)โ create a datatype with a new lower bound and extent.Create_struct(blocklengths, displacements, ...)โ create a general composite (struct) datatype.Create_subarray(sizes, subsizes, starts[, order])โ create a datatype for a subarray of a multidimensional array.Create_vector(count, blocklength, stride)โ create a vector (strided) datatype.Delete_attr(keyval)โ delete attribute value associated with a key.Dup()โ duplicate a datatype.Free()โ free the datatype.Free_keyval(keyval)โ free an attribute key for datatypes.Get_attr(keyval)โ retrieve attribute value by key.Get_contents()โ return the input arguments used to create a datatype.Get_envelope()โ return the number of input arguments used to create a datatype.Get_extent()โ return lower bound and extent of datatype.Get_name()โ get the print name for this datatype.Get_size()โ return the number of bytes occupied by entries in the datatype.Get_true_extent()โ return the true lower bound and extent of a datatype.Get_value_index(value, index)โ return a predefined pair datatype.Match_size(typeclass, size)โ find a datatype matching a specified size in bytes.
Unpack(inbuf, position, outbuf, comm)โ unpacks from contiguous memory according to datatype ๐ฆUnpack_external(datarep, inbuf, position, outbuf)โ unpacks from contiguous memory according to datatype ๐ฆdecode()โ convenience method for decoding a datatype, so cute of her ๐f2py(arg)โ (bestie the docs really just left this one blank, no cap ๐)free()โ calls Free if not null or predefined ๐งนfromcode(code)โ gets a predefined MPI datatype from a character code or type string ๐คfromhandle(handle)โ creates an object from an MPI handle โจfromint(arg, /)โ translates an integer handle to an object ๐ขpy2f()โ (again, nothing here, the void stared back ๐)tocode()โ gets a character code or type string from a predefined MPI datatype ๐คtoint()โ translates an object to an integer handle ๐ข
โจ Attributes Summary โจ
okay these are the lil properties you can just... read off a datatype, no method call needed, we love a low-effort slay ๐
combinerโ Combiner.contentsโ Contents.envelopeโ Envelope.extentโ Extent.handleโ MPI handle.is_namedโ Is a named datatype.is_predefinedโ Is a predefined datatype.lbโ Lower bound.nameโ Print name.sizeโ Size (in bytes).true_extentโ True extent.true_lbโ True lower bound.true_ubโ True upper bound.typecharโ Character code.typestrโ Type string.ubโ Upper bound.
โจ Methods Documentation โจ
the actual receipts, one method at a time ๐
Commit()
commits the datatype. that's it, that's the whole vibe โ she's committed now ๐
Return type
Create_contiguous(count)
creates a contiguous datatype ๐งฑ
Parameters
count(intโhttps://docs.python.org/3/library/functions.html#int)
Return type
Selfโhttps://docs.python.org/3/library/typing.html#typing.SelfCreate_darray(size, rank, gsizes, distribs, dargs, psizes, order=ORDER_C)โ bestie this one literally builds you a datatype for a distributed array sitting on top of Cartesian process grids. very main character of it. ๐ซsize(int)rank(int)gsizes(Sequence[int])distribs(Sequence[int])dargs(Sequence[int])psizes(Sequence[int])order(int)- Returns:
Self
Create_f90_complex(p, r)(classmethod) โ hands you back a bounded complex datatype. that's it that's the whole vibe. โจp(int)r(int)- Returns:
Self
Create_f90_integer(r)(classmethod) โ a bounded integer datatype, freshly served, no notes. ๐งr(int)- Returns:
Self
Create_f90_real(p, r)(classmethod) โ yep you guessed it, a bounded real datatype. iconic, consistent, we love a trio. ๐p(int)r(int)- Returns:
Self
Create_hindexed(blocklengths, displacements)โ makes an indexed datatype for you. ngl it's giving structured-data energy.
๐จ heads up bestie: the displacements here are measured in bytes. do not come for me, that's just how it is.
blocklengths(Sequence[int])displacements(Sequence[int])- Returns:
Self
Create_hindexed_block(blocklength, displacements)โ indexed datatype but every single block is the same size. uniform, tidy, lowkey obsessed. ๐
๐จ same warning, same energy: displacements are measured in bytes.
blocklength(int)displacements(Sequence[int])- Returns:
Self
Create_hvector(count, blocklength, stride)โ a vector (strided) datatype where the stride is in bytes. she's strutting fr fr. ๐ฅcount(int)blocklength(int)stride(int)- Returns:
Self
Create_indexed(blocklengths, displacements)โ an indexed datatype. the h-free sibling, still slaying. ๐blocklengths(Sequence[int])displacements(Sequence[int])- Returns:
Self
Create_indexed_block(blocklength, displacements)โ indexed datatype with constant-sized blocks. blocklength stays one single number, she doesn't do ranges. โจblocklength(int)displacements(Sequence[int])- Returns:
Self
Create_keyval(copy_fn=None, delete_fn=None, nopython=False)(classmethod) โ creates a brand new attribute key for datatypes and returns the key as anint. giving registry energy, honestly. ๐copy_fn(Callable[[Datatype, int, Any], Any] | None)delete_fn(Callable[[Datatype, int, Any], None] | None)nopython(bool)- Returns:
int
Create_resized(lb, extent)โ creates a datatype with a whole new lower bound and extent. glow-up but for byte layouts. ๐ฆlb(int)extent(int)- Returns:
Self
Create_struct(blocklengths, displacements, datatypes)(classmethod) โ the big one: a general composite (struct) datatype. this is the everything-everywhere-all-at-once of datatypes. ๐
๐จ you know the drill by now: displacements are measured in bytes.
blocklengths(Sequence[int])displacements(Sequence[int])datatypes(Sequence[Datatype])- Returns:
Self
Create_subarray(sizes, subsizes, starts, order=ORDER_C)โ creates a datatype for a subarray carved out of a multidimensional array. tiny slice, big energy. ๐sizes(Sequence[int])subsizes(Sequence[int])starts(Sequence[int])
order(int) โ anintbestie, that's the whole vibe ๐ซถ
Return type โ Self โจ
Create_vector(count, blocklength, stride) ๐ง
Makes a vector (strided) datatype. literally the moment you needed structure with โจgapsโจ in it, no cap ๐
Parameters
count(int)blocklength(int)stride(int)
Return type โ Self ๐ธ
Delete_attr(keyval) ๐
Yeets the attribute value that's hanging out with a key. bye boo ๐
Parameters
keyval(int)
Return type โ None ๐
Dup() ๐ฆ
Duplicates a datatype. it's giving copy-and-paste but make it MPI โจ
Return type โ Self ๐
Free() ๐ซถ
Frees the datatype. release it into the wild, bestie ๐๏ธ
Return type โ None ๐
classmethod Free_keyval(keyval) ๐
Frees an attribute key for datatypes. key said "my time has come" โจ
Parameters
keyval(int)
Return type โ int ๐
Get_attr(keyval) ๐ฅ
Retrieves an attribute value by key. like a lil lookup, but iconic ๐
Parameters
keyval(int)
Return type โ int | Any | None ๐
Get_contents() โญ
Returns the input arguments you used to create a datatype. it's the receipts, bestie, the whole origin story ๐งพโจ
Return type
tuple[list[int], list[int], list[int], list[Datatype]]
Get_envelope() ๐ธ
Returns how many input arguments went into creating a datatype. the headcount of the situation ๐
Return type
tuple[int, int, int, int, int]
Get_extent() ๐ฆ
Returns the lower bound and the extent of the datatype. two numbers, one destiny ๐ซ
Return type
tuple[int, int]
Get_name() ๐ท๏ธ
Gets the print name for this datatype. what it calls itself ๐
Return type โ str โจ
Get_size() ๐
Returns the number of bytes that the entries in the datatype occupy. size check but for memory, slay ๐
Return type โ int ๐ฅ
Get_true_extent() ๐
Returns the true lower bound and extent of a datatype. the honest version, no filter, periodt ๐ซถ
Return type
tuple[int, int]
classmethod Get_value_index(value, index) ๐
Returns a predefined pair datatype. a lil matched set, iconic behavior ๐
Parameters
value(Datatype)index(Datatype)
Return type โ Self โญ
classmethod Match_size(typeclass, size) ๐ง
Finds a datatype that matches a specified size in bytes. it's giving matchmaking but for types ๐
Parameters
typeclass(int)size(int)
Return type โ Self ๐
Pack(inbuf, outbuf, position, comm) ๐
Packs into contiguous memory according to the datatype. squish it in there bestie โจ
Parameters
inbuf(BufSpec)outbuf(BufSpec)position(int)comm(Comm)
Return type โ int ๐
Pack_external(datarep, inbuf, outbuf, position) ๐
Packs into contiguous memory according to the datatype.
Uses the portable data representation external32. travel-ready, no cap ๐งณโจ
Parameters
datarep(str)inbuf(BufSpec)outbuf(BufSpec)position(int)
Return type โ int ๐ฅ
Pack_external_size(datarep, count) ๐ฆ
Figures out how much space you need to pack a message.
Uses the portable data representation external32. same travel energy ๐ซ
Note: returns an upper bound measured in bytes. so it's an estimate, bestie, don't come for it ๐
Parameters
datarep(str)count(int)
Return type โ int ๐
Pack_size(count, comm) ๐
Figures out how much space you need to pack a message. the calculator moment ๐งฎโจ
Note: returns an upper bound measured in bytes. again โ upper bound, not the tea, just the ceiling ๐ซถ
Parameters
count(int)comm(Comm)
Return type โ int ๐
Set_attr(keyval, attrval) ๐
Stores an attribute value associated with a key. put it in the vault, bestie ๐
Parameters
keyval(int)attrval(Any)
Return type โ None ๐
Set_name(name) ๐ท๏ธ
Sets the print name for this datatype. rebrand szn โจ
Parameters
name(str)
Return type โ None ๐
Unpack(inbuf, position, outbuf, comm) ๐
Unpacks from contiguous memory according to the datatype. the un-squish, we love to see it ๐
Parameters
inbuf(BufSpec)position(int)outbuf(BufSpec)comm(Comm)
Return type โ int ๐ฅ
Unpack_external(datarep, inbuf, position, outbuf) ๐
Unpacks from contiguous memory according to the datatype.
Uses the portable data representation external32. ๐งณ
Parameters
datarep(str)inbuf(BufSpec)position(int)outbuf(BufSpec)
decode() โ convenience method for decoding a datatype ๐
Return type: tuple <https://docs.python.org/3/library/stdtypes.html#tuple>[Datatype <#mpi4py.MPI.Datatype>, str <https://docs.python.org/3/library/stdtypes.html#str>, dict <https://docs.python.org/3/library/stdtypes.html#dict>[str <https://docs.python.org/3/library/stdtypes.html#str>, Any <https://docs.python.org/3/library/typing.html#typing.Any>]]
classmethod f2py(arg)
- arg โ
int <https://docs.python.org/3/library/functions.html#int>
Return type: Datatype <#mpi4py.MPI.Datatype>
free() โ Call Free if not null or predefined. bestie it literally just tidies up ๐
Return type: None <https://docs.python.org/3/library/constants.html#None>
classmethod fromcode(code) โ Get a predefined MPI datatype from a character code or type string. iykyk โจ
- code โ
str <https://docs.python.org/3/library/stdtypes.html#str>
Return type: Datatype <#mpi4py.MPI.Datatype>
classmethod fromhandle(handle) โ Create an object from an MPI handle. giving very much "make me a real one from this int" ๐ช
- handle โ
int <https://docs.python.org/3/library/functions.html#int>
Return type: Datatype <#mpi4py.MPI.Datatype>
classmethod fromint(arg, /) โ Translate an integer handle to an object.
- arg โ
int <https://docs.python.org/3/library/functions.html#int>
Return type: Datatype <#mpi4py.MPI.Datatype>
py2f()
Return type: int <https://docs.python.org/3/library/functions.html#int>
tocode() โ Get a character code or type string from a predefined MPI datatype.
Return type: str <https://docs.python.org/3/library/stdtypes.html#str>
toint() โ Translate an object to an integer handle.
Return type: int <https://docs.python.org/3/library/functions.html#int>
โจ Attributes Documentation โจ
combinerโ Combiner.contentsโ Contents.envelopeโ Envelope.extentโ Extent.handleโ MPI handle.is_namedโ Is a named datatype.is_predefinedโ Is a predefined datatype.lbโ Lower bound.nameโ Print name.sizeโ Size (in bytes).true_extentโ True extent.true_lbโ True lower bound.true_ubโ True upper bound.typecharโ Character code.typestrโ Type string.ubโ Upper bound.
๐ฆ mpi4py.MPI.Distgraphcomm
class mpi4py.MPI.Distgraphcomm
Bases: Topocomm <#mpi4py.MPI.Topocomm>
Distributed graph topology intracommunicator. okay so this is the โจfancyโจ communicator for distributed graphs, no cap ๐
static __new__(cls, comm=None)
- comm โ
Distgraphcomm <#mpi4py.MPI.Distgraphcomm> | None <https://docs.python.org/3/library/constants.html#None>
Return type: Self <https://docs.python.org/3/library/typing.html#typing.Self>
Methods Summary ๐
Get_dist_neighbors()โ Return adjacency information for a distributed graph topology.Get_dist_neighbors_count()โ Return adjacency information for a distributed graph topology.
Methods Documentation ๐
Get_dist_neighbors() โ Return adjacency information for a distributed graph topology.
Return type: tuple <https://docs.python.org/3/library/stdtypes.html#tuple>[list <https://docs.python.org/3/library/stdtypes.html#list>[int <https://docs.python.org/3/library/functions.html#int>], list <https://docs.python.org/3/library/stdtypes.html#list>[int <https://docs.python.org/3/library/functions.html#int>], tuple <https://docs.python.org/3/library/stdtypes.html#tuple>[list <https://docs.python.org/3/library/stdtypes.html#list>[int <https://docs.python.org/3/library/functions.html#int>], list <https://docs.python.org/3/library/stdtypes.html#list>[int <https://docs.python.org/3/library/functions.html#int>]] | None <https://docs.python.org/3/library/constants.html#None>]
Get_dist_neighbors_count() โ Return adjacency information for a distributed graph topology.
Return type: int <https://docs.python.org/3/library/functions.html#int>
๐ mpi4py.MPI.Errhandler
class mpi4py.MPI.Errhandler
Bases: object <https://docs.python.org/3/library/functions.html#object>
Error handler. the one who handles the drama when MPI throws a fit ๐ ๐ญ
static __new__(cls, errhandler=None)
- errhandler โ
Errhandler <#mpi4py.MPI.Errhandler> | None <https://docs.python.org/3/library/constants.html#None>
Return type: Self <https://docs.python.org/3/library/typing.html#typing.Self>
Methods Summary ๐
Free()โ Free an error handler.f2py(arg)โ (no description, bestie, it just is)free()โ CallFreeif not null.fromhandle(handle)โ Create object from MPI handle.fromint(arg, /)โ Translate integer handle to object.py2f()โ (again, no description, we vibe)toint()โ Translate object to integer handle.
Attributes Summary โจ
handleโ MPI handle.
Methods Documentation ๐
Free() โ Free an error handler.
Return type: None <https://docs.python.org/3/library/constants.html#None>
classmethod f2py(arg)
- arg โ
int <https://docs.python.org/3/library/functions.html#int>
Return type: Errhandler <#mpi4py.MPI.Errhandler>
free() โ Call Free if not null.
Return type: None <https://docs.python.org/3/library/constants.html#None>
classmethod fromhandle(handle) โ Create object from MPI handle.
- handle โ
int <https://docs.python.org/3/library/functions.html#int>
Return type: Errhandler <#mpi4py.MPI.Errhandler>
classmethod fromint(arg, /) โ Translate integer handle to object.
- arg โ
int <https://docs.python.org/3/library/functions.html#int>
Return type: Errhandler <#mpi4py.MPI.Errhandler>
py2f()
toint()โ bestie this one takes the object and hands you back the integer handle for it. that's it, that's the whole job. so iconic of it ๐
Return type: int
โจ Attributes Documentation โจ
handleโ the raw MPI handle, just vibing there as an attribute. this is the actual underlying thing, the real one, the main character ๐
๐ฆ mpi4py.MPI.File ๐ฆ
class mpi4py.MPI.File
Bases: object
okay so this is the File I/O context, periodt. it's the whole vibe for doing file stuff in MPI โ collective reads, collective writes, the works. lowkey one of the most useful little objects in the whole module ๐ซถ
static __new__(cls, file=None)
the constructor situation. ngl it's static and it's __new__, so yes it's doing the fancy object-creation dance ๐
Parameters:
- file (
File|None) โ the file you're wrapping up in a fresh object, orNoneif you're not passing one. your call, bestie ๐
Return type: Self โ it hands you back an instance of itself, as is only correct โจ
โจ Methods Summary โจ
okay bestie, here's the whole menu of what a File object can do for you โ every single method, no skips, no gatekeeping ๐
Call_errhandler(errorcode)โ rings up the error handler that's installed on a file. like, calling in backup for the drama ๐ซถClose()โ closes a file. bye babe, it was real ๐โจCreate_errhandler(errhandler_fn)โ builds you a shiny new error handler, but for files specifically ๐Delete(filename[, info])โ deletes a file. gone, reduced to atoms ๐Get_amode()โ hands back the file access mode.Get_atomicity()โ hands back the atomicity mode.Get_byte_offset(offset)โ gives you the absolute byte position in the file ๐Get_errhandler()โ gets the error handler for a file.Get_group()โ lets you access the group of processes that opened the file. the whole squad, together ๐Get_info()โ returns the current hints for a file.Get_position()โ returns the current position of the individual file pointer.Get_position_shared()โ returns the current position of the shared file pointer.Get_size()โ returns the file size.Get_type_extent(datatype)โ returns the extent ofdatatypein the file.Get_view()โ returns the file view. main character reveal energy ๐Iread(buf)โ nonblocking read using the individual file pointer.Iread_all(buf)โ nonblocking collective read using the individual file pointer.Iread_at(offset, buf)โ nonblocking read using an explicit offset.Iread_at_all(offset, buf)โ nonblocking collective read using an explicit offset.Iread_shared(buf)โ nonblocking read using the shared file pointer.Iwrite(buf)โ nonblocking write using the individual file pointer.Iwrite_all(buf)โ nonblocking collective write using the individual file pointer.Iwrite_at(offset, buf)โ nonblocking write using an explicit offset.Iwrite_at_all(offset, buf)โ nonblocking collective write using an explicit offset.Iwrite_shared(buf)โ nonblocking write using the shared file pointer.Open(comm, filename[, amode, info])โ opens a file. the classic, the icon, the moment ๐Preallocate(size)โ preallocates storage space for a file. manifesting that space before you even need it ๐ฎRead(buf[, status])โ read using the individual file pointer.Read_all(buf[, status])โ collective read using the individual file pointer.Read_all_begin(buf)โ starts a split collective read using the individual file pointer.Read_all_end(buf[, status])โ wraps up a split collective read that was using the individual file pointer ๐Read_at(offset, buf[, status])โ reads at an offset you literally hand it, no pointer drama โจRead_at_all(offset, buf[, status])โ the collective version of reading at an explicit offset ๐Read_at_all_begin(offset, buf)โ kicks off a split collective read at an explicit offset (the "begin" half of the glow-up) ๐ฆRead_at_all_end(buf[, status])โ and this is the "end" half, completing that split collective read at an explicit offset ๐ธRead_ordered(buf[, status])โ collective read that goes through the shared file pointer ๐Read_ordered_begin(buf)โ starts a split collective read using the shared file pointer ๐ซถRead_ordered_end(buf[, status])โ completes a split collective read using the shared file pointer ๐ญRead_shared(buf[, status])โ read using the shared file pointer, periodt ๐ฅSeek(offset[, whence])โ moves the individual file pointer to wherever you want ๐Seek_shared(offset[, whence])โ same energy, but for the shared file pointer ๐Set_atomicity(flag)โ sets the atomicity mode โญSet_errhandler(errhandler)โ sets the error handler for a file ๐Set_info(info)โ sets new values for the hints tied to a file ๐Set_size(size)โ sets the file size ๐Set_view([disp, etype, filetype, datarep, info])โ sets the file view ๐งSync()โ makes all previous writes actually get transferred to the storage device ๐Write(buf[, status])โ writes using the individual file pointer ๐Write_all(buf[, status])โ collective write using the individual file pointer โจWrite_all_begin(buf)โ starts a split collective write using the individual file pointer ๐Write_all_end(buf[, status])โ completes a split collective write using the individual file pointer ๐ฆWrite_at(offset, buf[, status])โ write using an explicit offset ๐ธWrite_at_all(offset, buf[, status])โ collective write using an explicit offset ๐Write_at_all_begin(offset, buf)โ starts a split collective write using an explicit offset ๐ซถWrite_at_all_end(buf[, status])โ completes a split collective write using an explicit offset ๐ญWrite_ordered(buf[, status])โ collective write using the shared file pointer ๐ฅWrite_ordered_begin(buf)โ starts a split collective write using the shared file pointer ๐Write_ordered_end(buf[, status])โ completes a split collective write using the shared file pointer ๐Write_shared(buf[, status])โ write using the shared file pointer โญf2py(arg)โ no description, the docs just left it here like an unsent text ๐ not making anything up for it, bestie.free()โ CallCloseif not null. that's it, that's the whole job ๐ซถfromhandle(handle)โ Create object from MPI handle.fromint(arg, /)โ Translate integer handle to object. (yes, that/means arg is positional-only, iykyk)py2f()โ also description-less ๐ the table just vibes.toint()โ Translate object to integer handle. the reverse glow-up โจ
๐ Attributes Summary ๐
the lil properties she carries around with her, periodt:
amodeโ Access mode.atomicityโ Atomicity mode.groupโ Group.group_rankโ Group rank.group_sizeโ Group size.handleโ MPI handle.infoโ Info hints.sizeโ Size (in bytes).
๐ Methods Documentation ๐
okay now the actual receipts, one method at a time, no skimming:
Call_errhandler(errorcode)
Call the error handler installed on a file. ๐ฃ
Parameters
- errorcode โ
int
Return type โ None
Close()
Close a file. ๐ช say bye bestie.
Return type โ None
classmethod Create_errhandler(errhandler_fn)
Create a new error handler for files. custom handler, main character energy โจ
Parameters
- errhandler_fn โ
Callable[[File, int], None]
Return type โ Errhandler
classmethod Delete(filename, info=INFO_NULL)
Delete a file. ๐๏ธ note the default: info is INFO_NULL unless you say otherwise.
Parameters
- filename โ
PathLike | str | bytes - info โ
Info
Return type โ None
Get_amode()
Return the file access mode.
Return type โ int
Get_atomicity()
Return the atomicity mode.
Return type โ bool
Get_byte_offset(offset)
Return the absolute byte position in the file. ๐
Note: Input offset is measured in etype units relative to the current file view.
Parameters
- offset โ
int
Return type โ int
Get_errhandler()
Get the error handler for a file.
Return type โ Errhandler
Get_group()
Access the group of processes that opened the file. ๐ฏ
Return type โ Group
Get_info()
Return the current hints for a file.
Return type โ Info
Get_position()
Return the current position of the individual file pointer.
Note: Position is measured in etype units relative to the current file view.
Return type โ int
Get_position_shared()
Return the current position of the shared file pointer.
Note: Position is measured in etype units relative to the current view.
Return type โ int
Get_size()
Return the file size.
Return type โ int
Get_type_extent(datatype)
Return the extent of datatype in the file.
Parameters
- datatype โ
Datatype
Return type โ int
Get_view()
Return the file view. ๐
Return type โ tuple[int, Datatype, Datatype, str]
โจ and now the I/O girlies, all of them returning a Request โจ
Iread(buf)
Nonblocking read using individual file pointer.
Parameters
- buf โ
BufSpec
Return type โ Request
Iread_all(buf)
Nonblocking collective read using individual file pointer.
Parameters
- buf โ
BufSpec
Return type โ Request
Iread_at(offset, buf)
Nonblocking read using explicit offset.
Parameters
- offset โ
int - buf โ
BufSpec
Return type โ Request
Iread_at_all(offset, buf)
Nonblocking collective read using explicit offset.
Parameters
- offset โ
int - buf โ
BufSpec
Return type โ Request
Iread_shared(buf)
Nonblocking read using shared file pointer.
Parameters
- buf โ
BufSpec
Return type โ Request
Iwrite(buf)
Nonblocking write using individual file pointer. โ๏ธ
Parameters
- buf โ
BufSpec
Return type โ Request
Iwrite_all(buf)
Nonblocking collective write using individual file pointer.
Parameters
- buf โ
BufSpec
Return type โ Request
Iwrite_at(offset, buf)
Nonblocking write using explicit offset.
Parameters
offset(int)buf(BufSpec)
Return type: Request
Iwrite_at_all(offset, buf)
Nonblocking collective write, but using an explicit offset instead of a file pointer. yes bestie, same energy as the others, just a different flavor of write ๐
Parameters
offset(int)buf(BufSpec)
Return type: Request
Iwrite_shared(buf)
Nonblocking write using the shared file pointer. shared pointer moment โจ
Parameters
buf(BufSpec)
Return type: Request
classmethod Open(comm, filename, amode=MODE_RDONLY, info=INFO_NULL)
Open a file. the whole gateway drug to file I/O fr fr ๐
Parameters
comm(Intracomm)filename(PathLike|str|bytes)amode(int)info(Info)
Return type: Self
Preallocate(size)
Preallocate storage space for a file. reserve the vibes ahead of time, no cap
Parameters
size(int)
Return type: None
Read(buf, status=None)
Read using the individual file pointer.
Parameters
buf(BufSpec)status(Status|None)
Return type: None
Read_all(buf, status=None)
Collective read using the individual file pointer. everyone reads together, main character ensemble energy ๐
Parameters
buf(BufSpec)status(Status|None)
Return type: None
Read_all_begin(buf)
Start a split collective read using the individual file pointer. it's giving "we're doing this in two steps" ๐
Parameters
buf(BufSpec)
Return type: None
Read_all_end(buf, status=None)
Complete a split collective read using the individual file pointer. the second half of the two-step, slay ๐ฆ
Parameters
buf(BufSpec)status(Status|None)
Return type: None
Read_at(offset, buf, status=None)
Read using an explicit offset.
Parameters
offset(int)buf(BufSpec)status(Status|None)
Return type: None
Read_at_all(offset, buf, status=None)
Collective read using an explicit offset.
Parameters
offset(int)buf(BufSpec)status(Status|None)
Return type: None
Read_at_all_begin(offset, buf)
Start a split collective read using an explicit offset.
Parameters
offset(int)buf(BufSpec)
Return type: None
Read_at_all_end(buf, status=None)
Complete a split collective read using an explicit offset.
Parameters
buf(BufSpec)status(Status|None)
Return type: None
Read_ordered(buf, status=None)
Collective read using the shared file pointer.
Parameters
buf(BufSpec)status(Status|None)
Return type: None
Read_ordered_begin(buf)
Start a split collective read using the shared file pointer.
Parameters
buf(BufSpec)
Return type: None
Read_ordered_end(buf, status=None)
Complete a split collective read using the shared file pointer.
Parameters
buf(BufSpec)status(Status|None)
Return type: None
Read_shared(buf, status=None)
Read using the shared file pointer.
Parameters
buf(BufSpec)status(Status|None)
Return type: None
Seek(offset, whence=SEEK_SET)
Update the individual file pointer. move that cursor bestie, we're going places ๐
Parameters
offset(int)whence(int)
Return type: None
Seek_shared(offset, whence=SEEK_SET)
Update the shared file pointer. same cursor behavior but make it communal โจ
Parameters
offset(int)whence(int)
Return type: None
Set_atomicity(flag)
Set the atomicity mode.
Parameters
flag(bool)
Return type: None
Set_errhandler(errhandler)
Set the error handler for a file.
Parameters
errhandler(Errhandler)
Return type: None
Set_info(info)
Set new values for the hints associated with a file.
Parameters
info(Info)
Return type: None
Set_size(size)
Set the file size.
Parameters
size(int)
Return type: None
Set_view(disp=0, etype=BYTE, filetype=None, datarep='native', info=INFO_NULL)
Set the file view. the glow-up of file configuration ๐
Parameters
disp(int)etype(Datatype)filetype(DatatypeorNone) ๐datarep(str)info(Info)
Return type: None
Sync()
Causes all previous writes to be transferred to the storage device. Like, it's the "bestie I need you to actually commit" button. Push those writes all the way out, no cap. ๐พโจ
Return type: None
Write(buf, status=None)
Write using individual file pointer. Your own lil pointer, your own lil write. ๐๏ธ
Parameters
buf(BufSpec)status(StatusorNone)
Return type: None
Write_all(buf, status=None)
Collective write using individual file pointer. Everybody's writing, everybody's got their own pointer. Group project but make it functional. ๐ซถ
Parameters
buf(BufSpec)status(StatusorNone)
Return type: None
Write_all_begin(buf)
Start a split collective write using individual file pointer. This is the begin half of the split โ the setup era. โจ
Parameters
buf(BufSpec)
Return type: None
Write_all_end(buf, status=None)
Complete a split collective write using individual file pointer. And this is the end half โ closing the loop, we love a follow-through. ๐
Parameters
buf(BufSpec)status(StatusorNone)
Return type: None
Write_at(offset, buf, status=None)
Write using explicit offset. You say exactly where, no guessing games. ๐
Parameters
offset(int)buf(BufSpec)status(StatusorNone)
Return type: None
Write_at_all(offset, buf, status=None)
Collective write using explicit offset. Everyone writes, everyone gets told the exact spot. Coordinated queen behaviour. ๐
Parameters
offset(int)buf(BufSpec)status(StatusorNone)
Return type: None
Write_at_all_begin(offset, buf)
Start a split collective write using explicit offset. The opening act of the explicit-offset split collective. ๐ฌ
Parameters
offset(int)buf(BufSpec)
Return type: None
Write_at_all_end(buf, status=None)
Complete a split collective write using explicit offset. And the finale. Curtain, applause, data written. ๐ธ
Parameters
buf(BufSpec)status(StatusorNone)
Return type: None
Write_ordered(buf, status=None)
Collective write using shared file pointer. One shared pointer for the whole squad โ orderly, no fighting over the spot. ๐ง
Parameters
buf(BufSpec)status(StatusorNone)
Return type: None
Write_ordered_begin(buf)
Start a split collective write using shared file pointer. Split collective, shared-pointer flavour, part one. ๐
Parameters
buf(BufSpec)
Return type: None
Write_ordered_end(buf, status=None)
Complete a split collective write using shared file pointer. Shared-pointer split collective, part two, and we're done. ๐
Parameters
buf(BufSpec)status(StatusorNone)
Return type: None
Write_shared(buf, status=None)
Write using shared file pointer. Non-split version, shared pointer, same energy. ๐
Parameters
buf(BufSpec)status(StatusorNone)
Return type: None
classmethod f2py(arg)
Yep, it's a classmethod, and yep, it takes one arg.
Parameters
arg(int)
Return type: File
free()
Call Close if not null. Tidy up, bestie. If it's not null, close it. No loose ends. ๐งน
Return type: None
classmethod fromhandle(handle)
Create object from MPI handle. Hand it the handle, get an object back. Glow-up in one call. โจ
Parameters
handle(int)
Return type: File
classmethod fromint(arg, /)
Translate integer handle to object. Numbers in, object out. (Note the / โ that arg is positional-only, iykyk.) ๐
Parameters
arg(int)
Return type: File
py2f()
Python to Fortran, babes.
Return type: int
toint()
Translate object to integer handle. The reverse glow-up: object in, integer out. ๐
Return type: int
๐ Attributes Documentation ๐
amodeโ Access mode. ๐atomicityโ Atomicity mode. โ๏ธgroupโ Group. ๐ฏgroup_rankโ Group rank. ๐ขgroup_sizeโ Group size. ๐handleโ MPI handle. ๐infoโ Info hints. ๐กsizeโ Size (in bytes). ๐ฆ
๐ฆ mpi4py.MPI.Graphcomm ๐ฆ
class mpi4py.MPI.Graphcomm
Bases: Topocomm
General graph topology intracommunicator. Okay so this one isn't your basic line-up-in-a-row communicator โ it's a whole graph, bestie. Nodes and edges, connections all over the place, it's giving "my social circle is not a straight line." ๐ธ๏ธ๐
static __new__(cls, comm=None)
The constructor moment. โจ
Parameters
comm(GraphcommorNone)
Return type: Self
๐ Methods Summary ๐
Get_dims()โ Return the number of nodes and edges. ๐Get_neighbors(rank)โ Return list of neighbors of a process. ๐ซGet_neighbors_count(rank)โ Return number of neighbors of a process. ๐ขGet_topo()โ Return index and edges. ๐บ๏ธ
๐ Attributes Summary ๐
okay bestie these are the vibes this object is carrying around, all of them, no skips:
dimsโ Number of nodes and edges.edgesโ Edges.indexโ Index.nedgesโ Number of edges.neighborsโ Neighbors.nneighborsโ Number of neighbors.nnodesโ Number of nodes.topoโ Topology information.
๐ Methods Documentation ๐
Get_dims()
Return the number of nodes and edges.
Return type: tuple[int, int]
Get_neighbors(rank)
Return list of neighbors of a process.
Parameters: rank (int)
Return type: list[int]
Get_neighbors_count(rank)
Return number of neighbors of a process.
Parameters: rank (int)
Return type: int
Get_topo()
Return index and edges.
Return type: tuple[list[int], list[int]]
๐ Attributes Documentation ๐
dimsโ Number of nodes and edges.edgesโ Edges.indexโ Index.nedgesโ Number of edges.neighborsโ Neighbors.nneighborsโ Number of neighbors.nnodesโ Number of nodes.topoโ Topology information.
๐ mpi4py.MPI.Grequest ๐
class mpi4py.MPI.Grequest
Bases: Request
Generalized request handler. iconic behavior tbh
static __new__(cls, request=None)
Parameters: request (Grequest | None)
Return type: Self
๐ซ Methods Summary ๐ซ
Complete()โ Notify that a user-defined request is complete.Start([query_fn, free_fn, cancel_fn, args, ...])โ Create and return a user-defined request.complete([obj])โ Notify that a user-defined request is complete.
๐ Methods Documentation ๐
Complete()
Notify that a user-defined request is complete.
Return type: None
classmethod Start(query_fn=None, free_fn=None, cancel_fn=None, args=None, kwargs=None)
Create and return a user-defined request.
Parameters:
query_fn(Callable[[...], None]|None)free_fn(Callable[[...], None]|None)cancel_fn(Callable[[...], None]|None)args(tuple[Any]|None)kwargs(dict[str, Any]|None)
Return type: Grequest
complete(obj=None)
Notify that a user-defined request is complete.
Parameters: obj (Any)
Return type: None
๐ธ mpi4py.MPI.Group ๐ธ
class mpi4py.MPI.Group
Bases: object
Group of processes. bestie this is literally your whole little squad ๐
static __new__(cls, group=None)
Parameters: group (Group | None)
Return type: Self
๐ Methods Summary ๐
Okay bestie, gather round ๐ here's the whole lineup of moves you can pull on a Group โ one bullet per method, nothing skipped, no crumbs left behind:
Compare(group)โ Compare two groups.Create_from_session_pset(session, pset_name)โ Create a new group from session and process set.Difference(group1, group2)โ Create a new group from the difference of two existing groups.Dup()โ Duplicate a group.Excl(ranks)โ Create a new group by excluding listed members.Free()โ Free a group.Get_rank()โ Return the rank of this process in a group.Get_size()โ Return the number of processes in a group.Incl(ranks)โ Create a new group by including listed members.Intersection(group1, group2)โ Create a new group from the intersection of two existing groups.Range_excl(ranks)โ Create a new group by excluding ranges of members.Range_incl(ranks)โ Create a new group by including ranges of members.Translate_ranks([ranks, group])โ Translate ranks in a group to those in another group.Union(group1, group2)โ Create a new group from the union of two existing groups.f2py(arg)free()โ CallFreeif not null or predefined.fromhandle(handle)โ Create object from MPI handle.fromint(arg, /)โ Translate integer handle to object.py2f()toint()โ Translate object to integer handle.
โจ Attributes Summary โจ
The lil properties you can peek at ๐:
handleโ MPI handle.rankโ Rank of this process.sizeโ Number of processes.
๐ Methods Documentation ๐
Down into the receipts ๐ โ every method, every parameter, every return type, exactly as it is.
Compare(group)
Compare two groups. Fr fr, it tells you how two groups relate ๐ซถ
Parameters
- group (
Groupโ#mpi4py.MPI.Group)
Return type: int โ https://docs.python.org/3/library/functions.html#int
classmethod Create_from_session_pset(session, pset_name)
Create a new group from session and process set. It's a classmethod, so it lives on the class itself ๐
Parameters
- session (
Sessionโ#mpi4py.MPI.Session) - pset_name (
strโhttps://docs.python.org/3/library/stdtypes.html#str)
Return type: Self โ https://docs.python.org/3/library/typing.html#typing.Self
classmethod Difference(group1, group2)
Create a new group from the difference of two existing groups. Subtraction but make it โจgroupsโจ
Parameters
- group1 (
Groupโ#mpi4py.MPI.Group) - group2 (
Groupโ#mpi4py.MPI.Group)
Return type: Self โ https://docs.python.org/3/library/typing.html#typing.Self
Dup()
Duplicate a group. A little copy of the whole vibe ๐ธ
Return type: Self โ https://docs.python.org/3/library/typing.html#typing.Self
Excl(ranks)
Create a new group by excluding listed members. Bye bye to the ones you don't want ๐
Parameters
- ranks (
Sequence[int]โhttps://docs.python.org/3/library/typing.html#typing.Sequence+https://docs.python.org/3/library/functions.html#int)
Return type: Self โ https://docs.python.org/3/library/typing.html#typing.Self
Free()
Free a group. Let it go, release the memory, main character move ๐
Return type: None โ https://docs.python.org/3/library/constants.html#None
Get_rank()
Return the rank of this process in a group.
Return type: int โ https://docs.python.org/3/library/functions.html#int
Get_size()
Return the number of processes in a group.
Return type: int โ https://docs.python.org/3/library/functions.html#int
Incl(ranks)
Create a new group by including listed members. Now this is the invite list ๐
Parameters
- ranks (
Sequence[int]โhttps://docs.python.org/3/library/typing.html#typing.Sequence+https://docs.python.org/3/library/functions.html#int)
Return type: Self โ https://docs.python.org/3/library/typing.html#typing.Self
Intersection(group1, group2) <span style="color:hotpink">(classmethod)</span>
okay so bestie, you take two groups that already exist and you make a brand new group out of the intersection of them โ like, only the members that are in BOTH. โจ
group1โ aGroup๐group2โ anotherGroup๐
Return type: Self
Range_excl(ranks)
creates a fresh group by excluding ranges of members. bye bye to those ranges ๐
ranksโSequence[tuple[int, int, int]]
Return type: Self
Range_incl(ranks)
same vibe but the opposite direction: makes a new group by including ranges of members. come on in, we saved you a seat ๐ซถ
ranksโSequence[tuple[int, int, int]]
Return type: Self
Translate_ranks(ranks=None, group=None)
this one translates ranks in a group into the ranks of another group. it's giving translator app but for process numbers ๐
ranksโSequence[int] | NonegroupโGroup | None
Return type: list[int]
Union(group1, group2) <span style="color:purple">(classmethod)</span>
the glow-up version: build a new group from the union of two existing groups. everybody's invited, it's a party ๐
group1โ aGroup๐group2โ aGroup๐
Return type: Self
f2py(arg) <span style="color:purple">(classmethod)</span>
argโint
Return type: Group
free()
calls Free โ but only if it's not null and not predefined. like, don't go freeing something that was never yours to free, bestie ๐ญ
Return type: None
fromhandle(handle) <span style="color:purple">(classmethod)</span>
creates an object straight from an MPI handle. handle in, object out โจ
handleโint
Return type: Group
fromint(arg, /) <span style="color:purple">(classmethod)</span>
translates an integer handle into an object. (note the / โ that arg is positional-only, no keyword games ๐ฅ)
argโint
Return type: Group
py2f()
Return type: int
toint()
translates an object into an integer handle. the reverse glow-up ๐
Return type: int
Attributes Documentation โจ
handleโ MPI handle.rankโ rank of this process.sizeโ number of processes.
mpi4py.MPI.InPlaceType ๐
class mpi4py.MPI.InPlaceType
Bases: object
type of IN_PLACE. that's it, that's the whole job ๐
__new__(cls) <span style="color:cyan">(static)</span>
Return type: Self
mpi4py.MPI.Info ๐ธ
class mpi4py.MPI.Info
Bases: object
info object. it holds info. iconic behaviour honestly ๐
__new__(cls, info=None) <span style="color:cyan">(static)</span>
infoโInfo | None
Return type: Self
Methods Summary โจ
okay bestie, this is the whole vibe check on Info methods โ every single one, no skips, no cap. ๐
Create([items])โ Create a new info object.Create_env([args])โ Create a new environment info object.Delete(key)โ Remove a (key, value) pair from info.Dup()โ Duplicate an existing info object.Free()โ Free an info object.Get(key)โ Retrieve the value associated with a key.Get_nkeys()โ Return the number of currently defined keys in info.Get_nthkey(n)โ Return the n-th defined key in info.Set(key, value)โ Store a value associated with a key.clear()โ Clear contents.copy()โ Copy contents.f2py(arg)โfree()โ Call Free if not null or predefined.fromhandle(handle)โ Create object from MPI handle.fromint(arg, /)โ Translate integer handle to object.get(key[, default])โ Retrieve value by key.items()โ Return list of items.keys()โ Return list of keys.pop(key, *default)โ Pop value by key.popitem()โ Pop first item.py2f()โtoint()โ Translate object to integer handle.update([items])โ Update contents.values()โ Return list of values.
Attributes Summary ๐ธ
handleโ MPI handle.
Methods Documentation ๐ซถ
classmethod Create(items=None)
Create a new info object. โจ
Parameters
items (Info <#mpi4py.MPI.Info> | Mapping <https://docs.python.org/3/library/typing.html#typing.Mapping>[str <https://docs.python.org/3/library/stdtypes.html#str>, str <https://docs.python.org/3/library/stdtypes.html#str>] | Iterable <https://docs.python.org/3/library/typing.html#typing.Iterable>[tuple <https://docs.python.org/3/library/stdtypes.html#tuple>[str <https://docs.python.org/3/library/stdtypes.html#str>, str <https://docs.python.org/3/library/stdtypes.html#str>]] | None <https://docs.python.org/3/library/constants.html#None>)
Return type
Self <https://docs.python.org/3/library/typing.html#typing.Self>
classmethod Create_env(args=None)
Create a new environment info object. ๐ฆ
Parameters
args (Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[str <https://docs.python.org/3/library/stdtypes.html#str>] | None <https://docs.python.org/3/library/constants.html#None>)
Return type
Self <https://docs.python.org/3/library/typing.html#typing.Self>
Delete(key)
Remove a (key, value) pair from info. ๐
Parameters
- key โ
str <https://docs.python.org/3/library/stdtypes.html#str>
Return type
None <https://docs.python.org/3/library/constants.html#None>
Dup()
Duplicate an existing info object. ๐
Return type
Self <https://docs.python.org/3/library/typing.html#typing.Self>
Free()
Free an info object. ๐ง
Return type
None <https://docs.python.org/3/library/constants.html#None>
Get(key)
Retrieve the value associated with a key. ๐
Parameters
- key โ
str <https://docs.python.org/3/library/stdtypes.html#str>
Return type
str <https://docs.python.org/3/library/stdtypes.html#str> | None <https://docs.python.org/3/library/constants.html#None>
Get_nkeys()
Return the number of currently defined keys in info. ๐ข
Return type
int <https://docs.python.org/3/library/functions.html#int>
Get_nthkey(n)
Return the n-th defined key in info. ๐๏ธ
Parameters
Return type
str <https://docs.python.org/3/library/stdtypes.html#str>
Set(key, value)
Store a value associated with a key. ๐
Parameters
- key โ
str <https://docs.python.org/3/library/stdtypes.html#str> - value โ
str <https://docs.python.org/3/library/stdtypes.html#str>
Return type
None <https://docs.python.org/3/library/constants.html#None>
clear()
Clear contents. โจ
okay bestie we're still in our Info era and honestly? it's giving organized little dictionary energy ๐ no re-intro needed, let's just keep it rolling โจ
copy() Copy contents. A lil photocopy of your info object, no cap ๐ซถ
- Return type:
Self(https://docs.python.org/3/library/typing.html#typing.Self)
classmethod f2py(arg)
- Parameters:
arg(int) โhttps://docs.python.org/3/library/functions.html#int
- Return type:
Info(#mpi4py.MPI.Info)
free() Call Free if not null or predefined. Yeah it's literally called Free and it's doing exactly what it says on the tin ๐
- Return type:
None(https://docs.python.org/3/library/constants.html#None)
classmethod fromhandle(handle) Create object from MPI handle.
- Parameters:
handle(int) โhttps://docs.python.org/3/library/functions.html#int
- Return type:
Info(#mpi4py.MPI.Info)
classmethod fromint(arg, /) Translate integer handle to object.
- Parameters:
arg(int) โhttps://docs.python.org/3/library/functions.html#int
- Return type:
Info(#mpi4py.MPI.Info)
get(key, default=None) Retrieve value by key. Standard main-character lookup behaviour, periodt ๐
- Parameters:
key(str) โhttps://docs.python.org/3/library/stdtypes.html#strdefault(str|None) โhttps://docs.python.org/3/library/stdtypes.html#str,https://docs.python.org/3/library/constants.html#None
- Return type:
str|Noneโhttps://docs.python.org/3/library/stdtypes.html#str,https://docs.python.org/3/library/constants.html#None
items() Return list of items. Your whole little key-value lineup, served fresh ๐ธ
- Return type:
list[tuple[str, str]]โhttps://docs.python.org/3/library/stdtypes.html#list,https://docs.python.org/3/library/stdtypes.html#tuple,https://docs.python.org/3/library/stdtypes.html#str,https://docs.python.org/3/library/stdtypes.html#str
keys() Return list of keys.
- Return type:
list[str]โhttps://docs.python.org/3/library/stdtypes.html#list,https://docs.python.org/3/library/stdtypes.html#str
pop(key, *default) Pop value by key. Yank it right outta there, iconic ๐
- Parameters:
key(str) โhttps://docs.python.org/3/library/stdtypes.html#strdefault(str) โhttps://docs.python.org/3/library/stdtypes.html#str
- Return type:
str(https://docs.python.org/3/library/stdtypes.html#str)
popitem() Pop first item. Not last โ first. Read it twice bestie, it's not doing LIFO today ๐
- Return type:
tuple[str, str]โhttps://docs.python.org/3/library/stdtypes.html#tuple,https://docs.python.org/3/library/stdtypes.html#str,https://docs.python.org/3/library/stdtypes.html#str
py2f()
- Return type:
int(https://docs.python.org/3/library/functions.html#int)
toint() Translate object to integer handle.
- Return type:
int(https://docs.python.org/3/library/functions.html#int)
update(items=(), **kwds) Update contents. Glow-up your info object in place โจ
- Parameters:
items(Info|Mapping[str, str]|Iterable[tuple[str, str]]) โ#mpi4py.MPI.Info,https://docs.python.org/3/library/typing.html#typing.Mapping,https://docs.python.org/3/library/stdtypes.html#str,https://docs.python.org/3/library/stdtypes.html#str,https://docs.python.org/3/library/typing.html#typing.Iterable,https://docs.python.org/3/library/stdtypes.html#tuple,https://docs.python.org/3/library/stdtypes.html#str,https://docs.python.org/3/library/stdtypes.html#str,https://docs.python.org/3/library/stdtypes.html#str,https://docs.python.org/3/library/stdtypes.html#strkwds(str) โhttps://docs.python.org/3/library/stdtypes.html#str
- Return type:
None(https://docs.python.org/3/library/constants.html#None)
values() Return list of values.
- Return type:
list[str]โhttps://docs.python.org/3/library/stdtypes.html#list,https://docs.python.org/3/library/stdtypes.html#str
Attributes Documentation ๐
handle MPI handle.
mpi4py.MPI.Intercomm ๐ฆ
class mpi4py.MPI.Intercomm
Bases: Comm (#mpi4py.MPI.Comm)
Intercommunicator. That's the whole personality. Two groups, talking to each other, absolutely thriving ๐
static __new__(cls, comm=None)
- Parameters:
comm(Intercomm|None) โ#mpi4py.MPI.Intercomm,https://docs.python.org/3/library/constants.html#None
- Return type:
Self(https://docs.python.org/3/library/typing.html#typing.Self)
Methods Summary ๐
Create_from_groups(local_group, ...[, ...])โ Create communicator from group.Get_remote_group()โ Access the remote group associated with the inter-communicator.Get_remote_size()โ Intercommunicator remote size.Merge([high])โ Merge intercommunicator into an intracommunicator.
Attributes Summary โญ
remote_groupโ Remote group.remote_sizeโ Number of remote processes.
Methods Documentation ๐ซถ
classmethod Create_from_groups(local_group, local_leader, remote_group, remote_leader, stringtag='org.mpi4py', info=INFO_NULL, errhandler=None) Create communicator from group.
- Parameters:
local_group(Group) โ#mpi4py.MPI.Grouplocal_leader(int) โhttps://docs.python.org/3/library/functions.html#intremote_group(Group) โ#mpi4py.MPI.Groupremote_leader(int) โhttps://docs.python.org/3/library/functions.html#intstringtag(str) โhttps://docs.python.org/3/library/stdtypes.html#strinfo(Info) โ#mpi4py.MPI.Infoerrhandler(Errhandler|None) โ#mpi4py.MPI.Errhandler,https://docs.python.org/3/library/constants.html#None
- Return type:
Intracomm(#mpi4py.MPI.Intracomm)
Get_remote_group() Access the remote group associated with the inter-communicator.
- Return type:
Group(#mpi4py.MPI.Group)
Get_remote_size() Intercommunicator remote size.
- Return type:
int(https://docs.python.org/3/library/functions.html#int)
Merge(high=False) Merge intercommunicator into an intracommunicator. Two become one, no cap ๐
- Parameters:
high(bool) โhttps://docs.python.org/3/library/functions.html#bool
- Return type:
Intracomm(#mpi4py.MPI.Intracomm)
Attributes Documentation ๐ธ
remote_group Remote group.
remote_size Number of remote processes.
mpi4py.MPI.Intracomm ๐
class mpi4py.MPI.Intracomm
Bases: Comm (#mpi4py.MPI.Comm)
Intracommunicator. The classic, the blueprint, the moment ๐
static __new__(cls, comm=None)
- Parameters:
comm(Intracomm|None) โ#mpi4py.MPI.Intracomm,https://docs.python.org/3/library/constants.html#None
- Return type:
Self(https://docs.python.org/3/library/typing.html#typing.Self)
โจ Methods Summary โจ
okay bestie, here's the whole method menu for this class, and it's lowkey a lot but we're gonna get through it together. no cap. ๐
Accept(port_name[, info, root])โ Accept a request to form a new intercommunicator. ๐Cart_map(dims[, periods])โ Determine optimal process placement on a Cartesian topology. ๐บ๏ธConnect(port_name[, info, root])โ Make a request to form a new intercommunicator. ๐Create_cart(dims[, periods, reorder])โ Create cartesian communicator. ๐Create_dist_graph(sources, degrees, destinations)โ Create distributed graph communicator. ๐ธ๏ธCreate_dist_graph_adjacent(sources, destinations)โ Create distributed graph communicator. ๐ธ๏ธCreate_from_group(group[, stringtag, info, ...])โ Create communicator from group. ๐ฏCreate_graph(index, edges[, reorder])โ Create graph communicator. ๐Create_group(group[, tag])โ Create communicator from group. ๐ฏCreate_intercomm(local_leader, peer_comm, ...)โ Create intercommunicator. ๐Exscan(sendbuf, recvbuf[, op])โ Exclusive Scan. ๐Exscan_init(sendbuf, recvbuf[, op, info])โ Persistent Exclusive Scan. ๐Graph_map(index, edges)โ Determine optimal process placement on a graph topology. ๐บ๏ธIexscan(sendbuf, recvbuf[, op])โ Inclusive Scan. ๐Iscan(sendbuf, recvbuf[, op])โ Inclusive Scan. ๐Scan(sendbuf, recvbuf[, op])โ Inclusive Scan. ๐Scan_init(sendbuf, recvbuf[, op, info])โ Persistent Inclusive Scan. ๐Spawn(command[, args, maxprocs, info, root, ...])โ Spawn instances of a single MPI application. ๐Spawn_multiple(command[, args, maxprocs, ...])โ Spawn instances of multiple MPI applications. ๐exscan(sendobj[, op])โ Exclusive Scan. ๐scan(sendobj[, op])โ Inclusive Scan. ๐
๐ ๏ธ Methods Documentation ๐ ๏ธ
Accept(port_name, info=INFO_NULL, root=0)
Accept a request to form a new intercommunicator. it's literally the "hey bestie let's link up" of MPI. ๐
Parameters
port_name(strhttps://docs.python.org/3/library/stdtypes.html#str)info(Info#mpi4py.MPI.Info)root(inthttps://docs.python.org/3/library/functions.html#int)
Return type: Intercomm #mpi4py.MPI.Intercomm
Cart_map(dims, periods=None)
Determine optimal process placement on a Cartesian topology. it's giving "where should everyone sit" vibes. ๐บ๏ธ
Parameters
dims(Sequence[int] https://docs.python.org/3/library/typing.html#typing.Sequence https://docs.python.org/3/library/functions.html#int)periods(Sequence[bool] https://docs.python.org/3/library/typing.html#typing.Sequence https://docs.python.org/3/library/functions.html#bool |Nonehttps://docs.python.org/3/library/constants.html#None)
Return type: int https://docs.python.org/3/library/functions.html#int
Connect(port_name, info=INFO_NULL, root=0)
Make a request to form a new intercommunicator. it's giving main character energy. ๐
Parameters
port_name(strhttps://docs.python.org/3/library/stdtypes.html#str)info(Info#mpi4py.MPI.Info)root(inthttps://docs.python.org/3/library/functions.html#int)
Return type: Intercomm #mpi4py.MPI.Intercomm
Create_cart(dims, periods=None, reorder=False)
Create cartesian communicator. periodt. ๐
Parameters
dims(Sequence[int] https://docs.python.org/3/library/typing.html#typing.Sequence https://docs.python.org/3/library/functions.html#int)periods(Sequence[bool] https://docs.python.org/3/library/typing.html#typing.Sequence https://docs.python.org/3/library/functions.html#bool |Nonehttps://docs.python.org/3/library/constants.html#None)reorder(boolhttps://docs.python.org/3/library/functions.html#bool)
Return type: Cartcomm #mpi4py.MPI.Cartcomm
Create_dist_graph(sources, degrees, destinations, weights=None, info=INFO_NULL, reorder=False)
Create distributed graph communicator. lowkey iconic. ๐ธ๏ธ
Parameters
sources(Sequence[int] https://docs.python.org/3/library/typing.html#typing.Sequence https://docs.python.org/3/library/functions.html#int)- degrees (
Sequence[int]) โ the out-degree of every single node, one number per node, bestie ๐ซ - destinations (
Sequence[int]) โ where all those edges actually point, flattened out into one big sequence ๐ซถ - weights (
Sequence[int]orNone) โ optional edge weights, orNoneif you're keeping it unweighted and unbothered - info (
Info) โ anInfoobject, obviously ๐ - reorder (
bool) โ do we let the implementation renumber the nodes? yes or no, no in-between
Return type
Distgraphcomm โ a distributed graph communicator, iconic ๐
Create_dist_graph_adjacent(sources, destinations, sourceweights=None, destweights=None, info=INFO_NULL, reorder=False)
Create distributed graph communicator. Same energy as the one above, just in the adjacent (sparse) flavour ๐ฆ
Parameters
- sources (
Sequence[int]) โ where the edges come from ๐ซ - destinations (
Sequence[int]) โ where the edges go ๐ซถ - sourceweights (
Sequence[int]orNone) โ weights on the source side, orNoneif you don't care - destweights (
Sequence[int]orNone) โ weights on the destination side, orNonefor the unweighted vibe - info (
Info) โ anInfoobject, periodt - reorder (
bool) โ renumber the nodes or nah?
Return type
Distgraphcomm โ same deal ๐ธ
classmethod Create_from_group(group, stringtag='org.mpi4py', info=INFO_NULL, errhandler=None)
Create communicator from group. It's a classmethod, so it knows things about itself ๐
Parameters
- group (
Group) โ theGroupyou're building from ๐ - stringtag (
str) โ the string tag, defaulting to'org.mpi4py'(yes, exactly that string, don't go changing it) - info (
Info) โ anInfoobject - errhandler (
ErrhandlerorNone) โ your error handler, orNoneif you're rawdogging it ๐
Return type
Intracomm โ an intracommunicator, slay โจ
Create_graph(index, edges, reorder=False)
Create graph communicator. ๐ธ
Parameters
- index (
Sequence[int]) โ the index array, it's giving "adjacency list boundaries" ๐ซ - edges (
Sequence[int]) โ the edges themselves ๐ซถ - reorder (
bool) โ let the implementation renumber the nodes?
Return type
Graphcomm โ a graph communicator, bestie ๐
Create_group(group, tag=0)
Create communicator from group. Different flavour, same dream โจ
Parameters
- group (
Group) โ theGroupin question ๐ - tag (
int) โ a tag, defaulting to0(zero, as in nothing, as in the default)
Return type
Intracomm โ an intracommunicator ๐
Create_intercomm(local_leader, peer_comm, remote_leader, tag=0)
Create intercommunicator. For when you need two groups talking to each other, lowkey iconic ๐ฆ
Parameters
- local_leader (
int) โ the rank of the leader on your side ๐ซ - peer_comm (
Intracomm) โ theIntracommthat connects to the other side ๐ - remote_leader (
int) โ the rank of the leader on the other side ๐ซถ - tag (
int) โ a tag, defaulting to0
Return type
Intercomm โ an intercommunicator, periodt ๐
Exscan(sendbuf, recvbuf, op=SUM)
Exclusive Scan. Everyone gets the combination of everybody before them ๐
Parameters
- sendbuf (
BufSpecorInPlace) โ your input buffer, orInPlaceif you're feeling spicy ๐ฅ - recvbuf (
BufSpec) โ where the answer lands ๐ - op (
Op) โ the reduction operation, defaulting toSUM
Return type
None โ nothing comes back, it all goes into recvbuf โจ
Exscan_init(sendbuf, recvbuf, op=SUM, info=INFO_NULL)
Persistent Exclusive Scan. Same exclusive scan energy, but persistent, so you can fire it off again and again ๐ง
Parameters
- sendbuf (
BufSpecorInPlace) โ input buffer, orInPlace๐ฅ - recvbuf (
BufSpec) โ output buffer ๐ - op (
Op) โ the operation, defaulting toSUM - info (
Info) โ anInfoobject, defaulting toINFO_NULL
Return type
Prequest โ a persistent request, obsessed ๐ธ
Graph_map(index, edges)
Determine optimal process placement on a graph topology. Basically asking MPI "bestie, where should everybody sit?" ๐ซ
Parameters
- index (
Sequence[int]) โ the index array ๐ - edges (
Sequence[int]) โ the edges ๐ซถ
Return type
int โ an integer comes back, no cap โจ
Iexscan(sendbuf, recvbuf, op=SUM)
Inclusive Scan. Non-blocking edition ๐
Parameters
- sendbuf (
BufSpecorInPlace) โ input buffer, orInPlace๐ฅ - recvbuf (
BufSpec) โ output buffer ๐ - op (
Op) โ the operation, defaulting toSUM
Return type
Request โ a Request, go wait on it whenever ๐
Iscan(sendbuf, recvbuf, op=SUM)
Inclusive Scan. Also non-blocking, also inclusive ๐
Parameters
- sendbuf (
BufSpecorInPlace) โ input buffer, orInPlace๐ฅ - recvbuf (
BufSpec) โ output buffer ๐ - op (
Op) โ the operation, defaulting toSUM
Return type
Request โ a Request ๐
Scan(sendbuf, recvbuf, op=SUM)
Inclusive Scan. The blocking one, main character energy โญ
Parameters
- sendbuf (
BufSpecorInPlace) โ input buffer, orInPlace๐ฅ - recvbuf (
BufSpec) โ output buffer ๐ - op (
Op) โ the operation, defaulting toSUM
Return type
None โ it all goes into recvbuf, nothing comes back โจ
Scan_init(sendbuf, recvbuf, op=SUM, info=INFO_NULL)
Persistent Inclusive Scan. Inclusive scan, but it sticks around ๐ง
Parameters
- sendbuf (
BufSpecorInPlace) โ input buffer, orInPlace๐ฅ - recvbuf (
BufSpec) โ output buffer ๐ - op (
Op) โ the operation, defaulting toSUM - info (
Info) โ anInfoobject, defaulting toINFO_NULL
Return type
Prequest โ a persistent request, we love to see it ๐ธ
Spawn(command, args=None, maxprocs=1, info=INFO_NULL, root=0, errcodes=None)
Spawn instances of a single MPI application. You get to start up a whole new squad, and it's giving very much "go forth and compute" ๐ซ
Parameters
- command (
PathLikeorstrorbytes) โ the program to run โ a path-like, astr, orbytes, all three are valid bestie ๐ซถ - args (
Sequence[str]orNone) โ the arguments to hand it, orNone - maxprocs (
int) โ how many processes you want, defaulting to1 - info (
Info) โ anInfoobject, defaulting toINFO_NULL - root (
int) โ the root rank, defaulting to0 - errcodes (
list[int]orNone) โ where error codes get written, orNoneif you don't want them ๐
Return type
Intercomm โ an intercommunicator to your shiny new processes ๐
Spawn_multiple(command, args=None, maxprocs=None, info=INFO_NULL, root=0, errcodes=None)
Spawn instances of multiple MPI applications. Multiple apps, one call, absolute chaos in the best way ๐ฅ
Parameters
command(Sequence[PathLike | str | bytes]) โ the thing to run, as a sequence of path-likes, strings, or bytes ๐ซถargs(Sequence[Sequence[str]] | None) โ a sequence of argument sequences, orNonemaxprocs(Sequence[int] | None) โ how many procs per command, orNoneinfo(Sequence[Info] | Info) โ info objects, one or a whole sequence of themroot(int) โ the root rankerrcodes(list[list[int]] | None) โ the error codes you collect, orNone
Return type: Intercomm
exscan(sendobj, op=SUM)
Exclusive Scan. you get the combination of everything that came before you, not including you bestie โจ
Parameters
sendobj(Any) โ whatever you're sending inop(Op|Callable[[Any, Any], Any]) โ the operation, either anOpor a callable that takes twoAnys and gives back anAny
Return type: Any
scan(sendobj, op=SUM)
Inclusive Scan. this one does include you, main character behavior fr fr ๐
Parameters
sendobj(Any) โ the thing going inop(Op|Callable[[Any, Any], Any]) โ anOp, or a callable[[Any, Any], Any]situation
Return type: Any
๐ฆ mpi4py.MPI.Message ๐ฆ
class mpi4py.MPI.Message
Bases: object
Matched message. it's giving "your message has been found" energy ๐
static __new__(cls, message=None)
Parameters
message(Message|None) โ an existing message, orNone
Return type: Self
๐ Methods Summary ๐
Iprobe(comm[, source, tag, status])โ Nonblocking test for a matched message.Irecv(buf)โ Nonblocking receive of matched message.Probe(comm[, source, tag, status])โ Blocking test for a matched message.Recv(buf[, status])โ Blocking receive of matched message.f2py(arg)โ (no description, it's just chillin' there)free()โ Do nothing.fromhandle(handle)โ Create object from MPI handle.fromint(arg, /)โ Translate integer handle to object.iprobe(comm[, source, tag, status])โ Nonblocking test for a matched message.irecv()โ Nonblocking receive of matched message.probe(comm[, source, tag, status])โ Blocking test for a matched message.py2f()โ (also no description, we respect the mystery)recv([status])โ Blocking receive of matched message.toint()โ Translate object to integer handle.
๐ Attributes Summary ๐
handleโ MPI handle. the little integer that runs the whole show iykyk
๐ Methods Documentation ๐
classmethod Iprobe(comm, source=ANY_SOURCE, tag=ANY_TAG, status=None)
Nonblocking test for a matched message. checks without committing, no strings attached ๐
Parameters
comm(Comm) โ the communicatorsource(int) โ who you're listening fortag(int) โ the tag on the messagestatus(Status|None) โ where the status lands, orNone
Return type: Self | None
Irecv(buf)
Nonblocking receive of matched message. comes back instantly with a request, the data shows up later bestie ๐ธ
Parameters
buf(BufSpec) โ the buffer receiving the goods
Return type: Request
classmethod Probe(comm, source=ANY_SOURCE, tag=ANY_TAG, status=None)
Blocking test for a matched message. it WILL sit there and wait until something shows up, no cap ๐
Parameters
comm(Comm) โ the communicator in questionsource(int) โ the rank you're waiting ontag(int) โ the tag you're matchingstatus(Status|None) โ status object slot, orNone
Return type: Self
Recv(buf, status=None)โ blocking receive of a matched message, bestie. You sit there and wait, patiently, like you're waiting for your iced coffee. ๐
Parameters:
- buf (
BufSpec) - status (
Status|None)
Return type: None
classmethod f2py(arg)
Parameters: arg (int)
Return type: Message
free()โ do nothing. Literally nothing. It's giving "no thoughts, head empty". ๐
Return type: None
classmethod fromhandle(handle)โ create object from MPI handle.
Parameters: handle (int)
Return type: Message
classmethod fromint(arg, /)โ translate integer handle to object.
Parameters: arg (int)
Return type: Message
classmethod iprobe(comm, source=ANY_SOURCE, tag=ANY_TAG, status=None)โ nonblocking test for a matched message. Just a lil peek, no commitment. ๐
Parameters:
- comm (
Comm) - source (
int) - tag (
int) - status (
Status|None)
Return type: Self | None
irecv()โ nonblocking receive of matched message.
Return type: Request
classmethod probe(comm, source=ANY_SOURCE, tag=ANY_TAG, status=None)โ blocking test for a matched message.
Parameters:
- comm (
Comm) - source (
int) - tag (
int) - status (
Status|None)
Return type: Self
py2f()
Return type: int
recv(status=None)โ blocking receive of matched message.
Parameters: status (Status | None)
Return type: Any
toint()โ translate object to integer handle.
Return type: int
Attributes Documentation โจ
handleโ MPI handle. ๐
mpi4py.MPI.Op ๐ฆ
class mpi4py.MPI.Op
Bases: object
Reduction operation. Like, the operation that squishes a whole pile of values into one, and honestly? She's iconic for it. ๐ฅ
static __new__(cls, op=None)
Parameters: op (Op | None)
Return type: Self
Methods Summary ๐ธ
Create(function[, commute])โ create a user-defined reduction operation.Free()โ free a user-defined reduction operation.Is_commutative()โ query reduction operations for their commutativity.Reduce_local(inbuf, inoutbuf)โ apply a reduction operation to local data.f2py(arg)free()โ callFreeif not null or predefined.fromhandle(handle)โ create object from MPI handle.fromint(arg, /)โ translate integer handle to object.py2f()toint()โ translate object to integer handle.
Attributes Summary ๐
handleโ MPI handle.is_commutativeโ is a commutative operation.is_predefinedโ is a predefined operation.
Methods Documentation ๐
classmethod Create(function, commute=False)โ create a user-defined reduction operation, fr fr.
Parameters:
- function (
Callable[[Buffer, Buffer, Datatype], None]) - commute (
bool)
Return type: Self
Free()โ free a user-defined reduction operation. Say bye bestie, we're releasing you. ๐ญ
Return type: None
Is_commutative()โ query reduction operations for their commutativity.
Return type: bool
Reduce_local(inbuf, inoutbuf)โ apply a reduction operation to local data.
Parameters:
- inbuf (
BufSpec) - inoutbuf (
BufSpec)
Return type: None
classmethod f2py(arg)
Parameters: arg (int)
Return type: Op
free()โ callFreeif not null or predefined. Responsible queen behavior, honestly. โจ
Return type: None
classmethod fromhandle(handle) ๐
Okay bestie, this one is literally the glow-up spell for an MPI handle: Create object from MPI handle.
Parameters
handle(int)
Return type Op
classmethod fromint(arg, /) โจ
Translate integer handle to object. No cap.
Parameters
arg(int)
Return type Op
py2f() ๐ฆ
Return type int
toint() ๐
Translate object to integer handle. Periodt.
Return type int
Attributes Documentation ๐
handleโ MPI handle.is_commutativeโ Is a commutative operation.is_predefinedโ Is a predefined operation.
mpi4py.MPI.Pickle ๐
class mpi4py.MPI.Pickle
Bases: object
Pickle/unpickle Python objects. It's giving serialization main character energy.
static __new__(cls, pickle=None)
Parameters
pickle(Pickle|None)
Return type Self
Methods Summary ๐
dumps(obj)โ Serialize object to pickle data stream.dumps_oob(obj)โ Serialize object to pickle data stream and out-of-band buffers.loads(data)โ Deserialize object from pickle data stream.loads_oob(data, buffers)โ Deserialize object from pickle data stream and out-of-band buffers.
Attributes Summary ๐ธ
PROTOCOLโ Protocol version.THRESHOLDโ Out-of-band threshold.
Methods Documentation ๐ฅ
dumps(obj) ๐
Serialize object to pickle data stream.
Parameters
obj(Any)
Return type bytes
dumps_oob(obj) โจ
Serialize object to pickle data stream and out-of-band buffers.
Parameters
obj(Any)
Return type tuple[bytes, list[buffer]]
loads(data) ๐ฆ
Deserialize object from pickle data stream.
Parameters
data(Buffer)
Return type Any
loads_oob(data, buffers) ๐
Deserialize object from pickle data stream and out-of-band buffers.
Parameters
data(Buffer)buffers(Iterable[Buffer])
Return type Any
Attributes Documentation ๐
PROTOCOLโ Protocol version.THRESHOLDโ Out-of-band threshold.
mpi4py.MPI.Prequest ๐
class mpi4py.MPI.Prequest
Bases: Request
Persistent request handler. Lowkey iconic.
static __new__(cls, request=None)
Parameters
request(Prequest|None)
Return type Self
Methods Summary ๐
Parrived(partition)โ Test partial completion of a partitioned receive operation.Pready(partition)โ Mark a given partition as ready.Pready_list(partitions)โ Mark a sequence of partitions as ready.Pready_range(partition_low, partition_high)โ Mark a range of partitions as ready.Start()โ Initiate a communication with a persistent request.Startall(requests)โ Start a collection of persistent requests.
Methods Documentation ๐ฅ
Parrived(partition) ๐
Test partial completion of a partitioned receive operation.
Parameters
partition(int)
Return type bool
Pready(partition) โจ
Mark a given partition as ready.
Parameters
partition(int)
Return type None
Pready_list(partitions) ๐ฆ
Mark a sequence of partitions as ready.
Parameters
partitions(Sequence[int])
Return type None
Pready_range(partition_low, partition_high) ๐
Mark a range of partitions as ready.
Parameters
partition_low(int)partition_high(int)
Return type None
Start() ๐ฅ
Initiate a communication with a persistent request.
Return type None
classmethod Startall(requests) ๐
Start a collection of persistent requests.
requestsโ alistofPrequestobjects ๐ like, hand me the whole squad of pending requests at once, bestie
Return type: None โ she does the thing and gives you nothing back, and that's the whole point, no cap ๐ซถ
mpi4py.MPI.Request
class mpi4py.MPI.Request
Bases: object
Okay so this is the Request handler โจ the little object that holds onto a nonblocking operation so you can check on it later. It's giving "I'll text you when it's done" energy, and honestly? Iconic. ๐
static __new__(cls, request=None)
Not me casually dropping a static constructor on you ๐ yes, it's __new__, yes it's static, yes we're being fancy today.
Parameters:
requestโ aRequest, orNoneif you're feeling mysterious ๐
Return type: Self โ she hands back a brand new shiny Self, as one does ๐ธ
โจ Methods Summary โจ
okay bestie, here's the whole squad of methods, both the CamelCase version and the lowercase version, because this class said "why not both" and honestly? iconic of it ๐
Cancel()โ cancel a request. bye bye request ๐ซถFree()โ free a communication request. let it go, bestie, release the memoryGet_status([status])โ a non-destructive test for the completion of a request (peeks, doesn't disturb ๐)Get_status_all(requests[, statuses])โ non-destructive test for the completion of all the requestsGet_status_any(requests[, status])โ non-destructive test for the completion of any of the requestsGet_status_some(requests[, statuses])โ non-destructive test for completion of some requestsTest([status])โ test for the completion of a non-blocking operationTestall(requests[, statuses])โ test for completion of all previously initiated requestsTestany(requests[, status])โ test for completion of any previously initiated requestTestsome(requests[, statuses])โ test for completion of some previously initiated requestsWait([status])โ wait for a non-blocking operation to complete (this one actually blocks, no cap)Waitall(requests[, statuses])โ wait for all previously initiated requests to completeWaitany(requests[, status])โ wait for any previously initiated request to completeWaitsome(requests[, statuses])โ wait for some previously initiated requests to completecancel()โ cancel a request (the lowercase remix ๐)f2py(arg)โ no description given, it's giving mystery โจfree()โ callFreeif not nullfromhandle(handle)โ create object from MPI handlefromint(arg, /)โ translate integer handle to objectget_status([status])โ non-destructive test for the completion of a requestget_status_all(requests[, statuses])โ non-destructive test for the completion of all requestsget_status_any(requests[, status])โ non-destructive test for the completion of any requestsget_status_some(requests[, statuses])โ non-destructive test for completion of some requestspy2f()โ also no description, the manpage is keeping secrets ๐test([status])โ test for the completion of a non-blocking operationtestall(requests[, statuses])โ test for completion of all previously initiated requeststestany(requests[, status])โ test for completion of any previously initiated requesttestsome(requests[, statuses])โ test for completion of some previously initiated requeststoint()โ translate object to integer handlewait([status])โ wait for a non-blocking operation to complete
notice howGet_status/get_statusand friends are literally the same vibe twice? yeah. pick whichever one matches your code's aesthetic, they're both here, we don't gatekeep ๐
waitall(requests[, statuses])โ blocks until all the requests you already kicked off are done. every single one, bestie, no stragglers, no "almost there" ๐waitany(requests[, status])โ blocks until any one of your previously initiated requests completes. first one home gets the crown ๐waitsome(requests[, statuses])โ blocks until some of your previously initiated requests complete. not all, not one, just... some. iconic chaos ๐ฆ
โจ Attributes Summary โจ
handleโ the MPI handle. that's it, that's the whole vibe ๐
๐ Methods Documentation ๐
Cancel()
Cancel a request. ๐ซ
- Return type:
None <https://docs.python.org/3/library/constants.html#None>
Free()
Free a communication request. let it go, bestie, it's not yours anymore ๐๏ธ
- Return type:
None <https://docs.python.org/3/library/constants.html#None>
Get_status(status=None)
Non-destructive test for the completion of a request. peek at it, don't touch it ๐
- Parameters:
status(Status <#mpi4py.MPI.Status>|None <https://docs.python.org/3/library/constants.html#None>) - Return type:
bool <https://docs.python.org/3/library/functions.html#bool>
classmethod Get_status_all(requests, statuses=None)
Non-destructive test for the completion of all requests.
- Parameters:
requests(Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[Request <#mpi4py.MPI.Request>])statuses(list <https://docs.python.org/3/library/stdtypes.html#list>[Status <#mpi4py.MPI.Status>]|None <https://docs.python.org/3/library/constants.html#None>)
- Return type:
bool <https://docs.python.org/3/library/functions.html#bool>
classmethod Get_status_any(requests, status=None)
Non-destructive test for the completion of any requests.
- Parameters:
requests(Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[Request <#mpi4py.MPI.Request>])status(Status <#mpi4py.MPI.Status>|None <https://docs.python.org/3/library/constants.html#None>)
- Return type:
tuple <https://docs.python.org/3/library/stdtypes.html#tuple>[int <https://docs.python.org/3/library/functions.html#int>, bool <https://docs.python.org/3/library/functions.html#bool>]
classmethod Get_status_some(requests, statuses=None)
Non-destructive test for completion of some requests.
- Parameters:
requests(Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[Request <#mpi4py.MPI.Request>])statuses(list <https://docs.python.org/3/library/stdtypes.html#list>[Status <#mpi4py.MPI.Status>]|None <https://docs.python.org/3/library/constants.html#None>)
- Return type:
list <https://docs.python.org/3/library/stdtypes.html#list>[int <https://docs.python.org/3/library/functions.html#int>]|None <https://docs.python.org/3/library/constants.html#None>
Test(status=None)
Test for the completion of a non-blocking operation. lowkey just checking in, no waiting around ๐ซถ
- Parameters:
status(Status <#mpi4py.MPI.Status>|None <https://docs.python.org/3/library/constants.html#None>) - Return type:
bool <https://docs.python.org/3/library/functions.html#bool>
classmethod Testall(requests, statuses=None)
Test for completion of all previously initiated requests.
- Parameters:
requests(Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[Request <#mpi4py.MPI.Request>])statuses(list <https://docs.python.org/3/library/stdtypes.html#list>[Status <#mpi4py.MPI.Status>]|None <https://docs.python.org/3/library/constants.html#None>)
- Return type:
bool <https://docs.python.org/3/library/functions.html#bool>
classmethod Testany(requests, status=None)
Test for completion of any previously initiated request.
- Parameters:
requests(Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[Request <#mpi4py.MPI.Request>])status(Status <#mpi4py.MPI.Status>|None <https://docs.python.org/3/library/constants.html#None>)
- Return type:
tuple <https://docs.python.org/3/library/stdtypes.html#tuple>[int <https://docs.python.org/3/library/functions.html#int>, bool <https://docs.python.org/3/library/functions.html#bool>]
classmethod Testsome(requests, statuses=None)
Test for completion of some previously initiated requests.
- Parameters:
requests(Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[Request <#mpi4py.MPI.Request>])statuses(list <https://docs.python.org/3/library/stdtypes.html#list>[Status <#mpi4py.MPI.Status>]|None <https://docs.python.org/3/library/constants.html#None>)
- Return type:
list <https://docs.python.org/3/library/stdtypes.html#list>[int <https://docs.python.org/3/library/functions.html#int>]|None <https://docs.python.org/3/library/constants.html#None>
Wait(status=None)
Wait for a non-blocking operation to complete. sit down, hydrate, it'll be done when it's done ๐
- Parameters:
status(Status <#mpi4py.MPI.Status>|None <https://docs.python.org/3/library/constants.html#None>) - Return type:
Literal <https://docs.python.org/3/library/typing.html#typing.Literal>[True]
classmethod Waitall(requests, statuses=None)
Wait for all previously initiated requests to complete. all of them. every last one. periodt ๐ฅ
- Parameters:
requests(Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[Request <#mpi4py.MPI.Request>])statuses(list <https://docs.python.org/3/library/stdtypes.html#list>[Status <#mpi4py.MPI.Status>]|None <https://docs.python.org/3/library/constants.html#None>)
- Return type:
Literal <https://docs.python.org/3/library/typing.html#typing.Literal>[True]
classmethod Waitany(requests, status=None)
Wait for any previously initiated request to complete. first one to finish, you're the main character now โจ
- Parameters:
requests(Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[Request <#mpi4py.MPI.Request>])status(Status <#mpi4py.MPI.Status>|None <https://docs.python.org/3/library/constants.html#None>)
- Return type:
int <https://docs.python.org/3/library/functions.html#int>
classmethod Waitsome(requests, statuses=None)
Wait for some previously initiated requests to complete.
- Parameters:
requests(Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[Request <#mpi4py.MPI.Request>])statuses(list <https://docs.python.org/3/library/stdtypes.html#list>[Status <#mpi4py.MPI.Status>]|None <https://docs.python.org/3/library/constants.html#None>)
- Return type:
list <https://docs.python.org/3/library/stdtypes.html#list>[int <https://docs.python.org/3/library/functions.html#int>]|None <https://docs.python.org/3/library/constants.html#None>
cancel()
Cancel a request. same energy as Cancel(), just lowercase and chill ๐ง
- Return type:
None <https://docs.python.org/3/library/constants.html#None>
classmethod f2py(arg)
- Parameters:
arg(int <https://docs.python.org/3/library/functions.html#int>)
Return type: Request ๐
free() ๐
Calls Free if the thing isn't null. That's it, that's the whole job.
Return type: None
classmethod fromhandle(handle) ๐ช
Builds you a whole object out of an MPI handle. Glow-up from raw number to real class, no cap.
Parameters:
handle(int)
Return type: Request
classmethod fromint(arg, /) ๐
Takes an integer handle and translates it into the object. Same energy as fromhandle, different entry point.
Parameters:
arg(int)
Return type: Request
get_status(status=None) ๐
A non-destructive test for whether a request has finished. It peeks, it does not consume. Respectful king behavior.
Parameters:
status(Status|None)
Return type: bool
classmethod get_status_all(requests, statuses=None) ๐
Non-destructive test for the completion of all the requests. Everybody has to be done or it's a no from me.
Parameters:
requests(Sequence[Request])statuses(list[Status]|None)
Return type: bool
classmethod get_status_any(requests, status=None) โจ
Non-destructive test for the completion of any of the requests. One single one finishing is enough to make it slay.
Parameters:
requests(Sequence[Request])status(Status|None)
Return type: tuple[int, bool]
classmethod get_status_some(requests, statuses=None) ๐ธ
Non-destructive test for the completion of some of the requests. A little subset of finished vibes.
Parameters:
requests(Sequence[Request])statuses(list[Status]|None)
Return type: list[int] | None
py2f() ๐โก๏ธ๐ข
No description in the docs, bestie โ it just hands you back an int.
Return type: int
test(status=None) ๐งช
Tests whether a non-blocking operation has completed. Note this one is not the "non-destructive" crew โ it's the real test.
Parameters:
status(Status|None)
Return type: tuple[bool, Any | None]
classmethod testall(requests, statuses=None) ๐ฅ
Tests for the completion of all the requests you previously initiated. Full house only.
Parameters:
requests(Sequence[Request])statuses(list[Status]|None)
Return type: tuple[bool, list[Any] | None]
classmethod testany(requests, status=None) โญ
Tests for the completion of any previously initiated request. First one to cross the finish line gets the attention.
Parameters:
requests(Sequence[Request])status(Status|None)
Return type: tuple[int, bool, Any | None]
classmethod testsome(requests, statuses=None) ๐
Tests for the completion of some of the previously initiated requests. A lil group of overachievers, honestly iconic.
Parameters:
requests(Sequence[Request])statuses(list[Status]|None)
Return type: tuple[list[int] | None, list[Any] | None]
toint() ๐ข
Translates the object into an integer handle. The reverse glow-down, and I mean that with love.
Return type: int
wait(status=None) โณ
Waits for a non-blocking operation to complete. Yes, it will sit there and hold your hand until it's done. Loyal.
Parameters:
status(Status|None)
Return type: Any
classmethod waitall(requests, statuses=None) ๐ซถ
Waits for all previously initiated requests to complete. Every single one of them, no skipping, we are not leaving anybody behind.
Parameters:
requests(Sequence[Request])statuses(list[Status]|None)
Return type: list[Any]
classmethod waitany(requests, status=None) ๐ฆ
Waits for any previously initiated request to complete. Whichever one gets there first, that's the one we're celebrating.
Parameters:
requests(Sequence[Request])status(Status|None)
Return type: tuple[int, Any]
classmethod waitsome(requests, statuses=None) ๐
Waits for some of the previously initiated requests to complete. Not all of them โ just however many show up to the party.
Parameters:
requests(Sequence[Request])statuses(list[Status] |None)
Return type: tuple[list[int] | None, list[Any] | None]
Attributes Documentation ๐
handleโ MPI handle.
๐ธ mpi4py.MPI.Session ๐ธ
class mpi4py.MPI.Session
Bases: object
Okay bestie, this is the Session context โจ โ think of it as a whole vibe of MPI-ness that you can spin up, poke at, and shut down on its own terms.
static __new__(cls, session=None)
- Parameters โ
session(Session|None) - Return type โ
Self
Methods Summary ๐
Attach_buffer(buf)โ Attach a user-provided buffer for sending in buffered mode.Call_errhandler(errorcode)โ Call the error handler installed on a session.Create_errhandler(errhandler_fn)โ Create a new error handler for sessions.Create_group(pset_name)โ Create a new group from session and process set.Detach_buffer()โ Remove an existing attached buffer.Finalize()โ Finalize a session.Flush_buffer()โ Block until all buffered messages have been transmitted.Get_errhandler()โ Get the error handler for a session.Get_info()โ Return the current hints for a session.Get_nth_pset(n[, info])โ Name of the n-th process set.Get_num_psets([info])โ Number of available process sets.Get_pset_info(pset_name)โ Return the current hints for a session and process set.Iflush_buffer()โ Nonblocking flush for buffered messages.Init([info, errhandler])โ Create a new session.Set_errhandler(errhandler)โ Set the error handler for a session.f2py(arg)free()โ Call Finalize if not null.fromhandle(handle)โ Create object from MPI handle.fromint(arg, /)โ Translate integer handle to object.py2f()toint()โ Translate object to integer handle.
Attributes Summary ๐
handleโ MPI handle.
Methods Documentation ๐
Attach_buffer(buf)
Attach a user-provided buffer for sending in buffered mode. ๐ซโจ
- Parameters โ
buf(Buffer|None) - Return type โ
None
Call_errhandler(errorcode)
Call the error handler installed on a session. Like ringing the little alarm bell you set up earlier ๐ฃ
- Parameters โ
errorcode(int) - Return type โ
None
classmethod Create_errhandler(errhandler_fn)
Create a new error handler for sessions. Custom alarm bell, made by you ๐
- Parameters โ
errhandler_fn(Callable[[Session,int],None]) - Return type โ
Errhandler
Create_group(pset_name)
Create a new group from session and process set. Squish a session + a process set together and boom, a group ๐ซถ
- Parameters โ
pset_name(str)
Return type: Group ๐ซถ
Detach_buffer()
Say bye to a buffer you'd attached earlier โ it just takes the attached buffer back off the shelf, that's it.
- Return type:
Buffer|None
Finalize()
Wrap up a session. That's the whole job. ๐
- Return type:
None
Flush_buffer()
Blocks (like, actually waits) until every single buffered message has been transmitted. Nothing sneaky gets left in the queue, bestie. โจ
- Return type:
None
Get_errhandler()
Hands you the error handler that's hooked up to a session.
- Return type:
Errhandler
Get_info()
Returns the current hints for a session. The tea, basically. ๐
- Return type:
Info
Get_nth_pset(n, info=INFO_NULL)
Gives you the name of the n-th process set. No cap.
Parameters:
- n (
int) - info (
Info) - Return type:
str
Get_num_psets(info=INFO_NULL)
How many process sets are even available. The headcount. ๐
Parameters:
- info (
Info) - Return type:
int
Get_pset_info(pset_name)
Returns the current hints for a session and a process set โ both at once, iconic.
Parameters:
- pset_name (
str) - Return type:
Info
Iflush_buffer()
Same energy as flushing buffered messages, but nonblocking โ it does not sit there waiting. It hands you a request instead. ๐
- Return type:
Request
classmethod Init(info=INFO_NULL, errhandler=None)
Creates a brand new session. Main character origin story. โจ
Parameters:
- info (
Info) - errhandler (
Errhandler|None) - Return type:
Self
Set_errhandler(errhandler)
Sets the error handler for a session. Pick your handler, commit to it.
Parameters:
- errhandler (
Errhandler) - Return type:
None
classmethod f2py(arg)
Parameters:
- arg (
int) - Return type:
Session
free()
Calls Finalize if not null.
- Return type:
None
classmethod fromhandle(handle)
Builds an object straight from an MPI handle. ๐
Parameters:
- handle (
int) - Return type:
Session
classmethod fromint(arg, /)
Translates an integer handle into an object. Glow-up complete. ๐ธ
Parameters:
- arg (
int) - Return type:
Session
py2f()
- Return type:
int
toint()
Translates an object into an integer handle.
- Return type:
int
Attributes Documentation ๐
handle
MPI handle.
mpi4py.MPI.Status ๐
class mpi4py.MPI.Status
Bases: object
Status object.
static __new__(cls, status=None)
Parameters:
- status (
Status|None) - Return type:
Self
Methods Summary ๐ฆ
Get_count([datatype])โ Get the number of top level elements.Get_elements(datatype)โ Get the number of basic elements in a datatype.Get_error()โ Get message error.Get_source()โ Get message source.Get_tag()โ Get message tag.Is_cancelled()โ Test to see if a request was cancelled.Set_cancelled(flag)โ Set the cancelled state associated with a status.Set_elements(datatype, count)โ Set the number of elements in a status.Set_error(error)โ Set message error.Set_source(source)โ Set message source.Set_tag(tag)โ Set message tag.f2py(arg)py2f()tomemory()โ Return status memory view.
Attributes Summary ๐
cancelledโ Cancelled state.countโ Byte count.errorโ Message error.sourceโ Message source.tagโ Message tag.
Methods Documentation โจ
Get_count(datatype=BYTE)
Gives you the number of top level elements.
Parameters:
- datatype (
Datatype) - Return type:
int
Get_elements(datatype)
Gives you the number of basic elements in a datatype.
Parameters:
- datatype (
Datatype) - Return type:
int
โจ Get_error()
Gives you the message error. That's it, that's the whole thing ๐
- Return type โ
int
โจ Get_source()
Gives you the message source. Yes queen, it's right there ๐ธ
- Return type โ
int
โจ Get_tag()
Gives you the message tag. The little label on the message, iconic โจ
- Return type โ
int
โจ Is_cancelled()
Checks whether a request got cancelled. Lowkey useful, no cap ๐ฆ
- Return type โ
bool
โจ Set_cancelled(flag)
Sets the cancelled state that's associated with a status.
โ ๏ธ Heads up bestie: only reach for this one when you're implementing query callback functions for generalized requests. Not a casual-use situation, fr fr.
- Parameters
- flag โ
bool
- flag โ
- Return type โ
None
โจ Set_elements(datatype, count)
Sets the number of elements in a status. Bestie, we're literally counting โจ
โ ๏ธ Listen: this is only for when you're implementing query callback functions for generalized requests. Stay in your lane, it's giving specialized ๐
- Parameters
- datatype โ
Datatype - count โ
int
- datatype โ
- Return type โ
None
โจ Set_error(error)
Sets the message error.
- Parameters
- error โ
int
- error โ
- Return type โ
None
โจ Set_source(source)
Sets the message source.
- Parameters
- source โ
int
- source โ
- Return type โ
None
โจ Set_tag(tag)
Sets the message tag.
- Parameters
- tag โ
int
- tag โ
- Return type โ
None
โจ classmethod f2py(arg)
A classmethod, so you're calling it on the class itself, not on an instance. Main character energy ๐
- Parameters
- arg โ
list[int]
- arg โ
- Return type โ
Self
โจ py2f()
- Return type โ
list[int]
โจ tomemory()
Returns the status as a memory view. It's giving "here's the raw view" ๐
- Return type โ
memoryview
๐ Attributes Documentation
cancelled
Cancelled state.
count
Byte count.
error
Message error.
source
Message source.
tag
Message tag.
๐ mpi4py.MPI.Topocomm
class mpi4py.MPI.Topocomm
Bases: Intracomm
Topology intracommunicator. Bestie, this is the comm that actually knows who its neighbors are ๐ฆ
static __new__(cls, comm=None)
- Parameters
- comm โ
Topocomm | None
- comm โ
- Return type โ
Self
๐ Methods Summary
okay so here's the whole roster, and every single one of them is here, no skips, no cuts ๐
Ineighbor_allgather(sendbuf, recvbuf)โ Nonblocking Neighbor Gather to All.Ineighbor_allgatherv(sendbuf, recvbuf)โ Nonblocking Neighbor Gather to All Vector.Ineighbor_alltoall(sendbuf, recvbuf)โ Nonblocking Neighbor All to All.Ineighbor_alltoallv(sendbuf, recvbuf)โ Nonblocking Neighbor All to All Vector.Ineighbor_alltoallw(sendbuf, recvbuf)โ Nonblocking Neighbor All to All General.Neighbor_allgather(sendbuf, recvbuf)โ Neighbor Gather to All.Neighbor_allgather_init(sendbuf, recvbuf[, info])โ Persistent Neighbor Gather to All.Neighbor_allgatherv(sendbuf, recvbuf)โ Neighbor Gather to All Vector.Neighbor_allgatherv_init(sendbuf, recvbuf[, ...])โ Persistent Neighbor Gather to All Vector.Neighbor_alltoall(sendbuf, recvbuf)โ Neighbor All to All.Neighbor_alltoall_init(sendbuf, recvbuf[, info])โ Persistent Neighbor All to All.Neighbor_alltoallv(sendbuf, recvbuf)โ Neighbor All to All Vector.Neighbor_alltoallv_init(sendbuf, recvbuf[, info])โ Persistent Neighbor All to All Vector.Neighbor_alltoallw(sendbuf, recvbuf)โ Neighbor All to All General.Neighbor_alltoallw_init(sendbuf, recvbuf[, info])โ Persistent Neighbor All to All General.neighbor_allgather(sendobj)โ Neighbor Gather to All.neighbor_alltoall(sendobj)โ Neighbor All to All.
Attributes Summary ๐
degreesโ the number of incoming and outgoing neighbors, combined. bestie gets both directions, no cap ๐indegreeโ how many neighbors are pointing at you. incoming only ๐inedgesโ the incoming neighbors themselves. the whole list, not just the count โจinoutedgesโ incoming and outgoing neighbors, all in one place ๐ฆoutdegreeโ how many neighbors you're pointing at. outgoing only ๐คoutedgesโ the outgoing neighbors themselves ๐ธ
Methods Documentation ๐
Ineighbor_allgather(sendbuf, recvbuf)
Nonblocking Neighbor Gather to All. ๐โ๏ธ๐จ
Parameters
sendbuf(BufSpec)recvbuf(BufSpecB)
Return type Request
Ineighbor_allgatherv(sendbuf, recvbuf)
Nonblocking Neighbor Gather to All Vector. ๐
Parameters
sendbuf(BufSpec)recvbuf(BufSpecV)
Return type Request
Ineighbor_alltoall(sendbuf, recvbuf)
Nonblocking Neighbor All to All. ๐ฅ
Parameters
sendbuf(BufSpecB)recvbuf(BufSpecB)
Return type Request
Ineighbor_alltoallv(sendbuf, recvbuf)
Nonblocking Neighbor All to All Vector. โจ
Parameters
sendbuf(BufSpecV)recvbuf(BufSpecV)
Return type Request
Ineighbor_alltoallw(sendbuf, recvbuf)
Nonblocking Neighbor All to All General. ๐
Parameters
sendbuf(BufSpecW)recvbuf(BufSpecW)
Return type Request
Neighbor_allgather(sendbuf, recvbuf)
Neighbor Gather to All. ๐ธ
Parameters
sendbuf(BufSpec)recvbuf(BufSpecB)
Return type None
Neighbor_allgather_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent Neighbor Gather to All. ๐
Parameters
sendbuf(BufSpec)recvbuf(BufSpecB)info(Info)
Return type Prequest
Neighbor_allgatherv(sendbuf, recvbuf)
Neighbor Gather to All Vector. ๐ฆ
Parameters
sendbuf(BufSpec)recvbuf(BufSpecV)
Return type None
Neighbor_allgatherv_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent Neighbor Gather to All Vector. ๐
Parameters
sendbuf(BufSpec)recvbuf(BufSpecV)info(Info)
Return type Prequest
Neighbor_alltoall(sendbuf, recvbuf)
Neighbor All to All. โญ
Parameters
sendbuf(BufSpecB)recvbuf(BufSpecB)
Return type None
Neighbor_alltoall_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent Neighbor All to All. ๐
Parameters
sendbuf(BufSpecB)recvbuf(BufSpecB)info(Info)
Return type Prequest
Neighbor_alltoallv(sendbuf, recvbuf)
Neighbor All to All Vector. ๐
Parameters
sendbuf(BufSpecV)recvbuf(BufSpecV)
Return type None
Neighbor_alltoallv_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent Neighbor All to All Vector. ๐ง
Parameters
sendbuf(BufSpecV)recvbuf(BufSpecV)info(Info)
Return type Prequest
Neighbor_alltoallw(sendbuf, recvbuf)
Neighbor All to All General. ๐ซ
Parameters
sendbuf(BufSpecW)recvbuf(BufSpecW)
Return type None
Neighbor_alltoallw_init(sendbuf, recvbuf, info=INFO_NULL)
Persistent Neighbor All to All General. ๐ฎ
Parameters
sendbuf(BufSpecW)recvbuf(BufSpecW)info(Info)
Return type Prequest
neighbor_allgather(sendobj)
Neighbor Gather to All. ๐ซถ
Parameters sendobj (Any)
Return type list[Any]
neighbor_alltoall(sendobj)
Neighbor All to All. ๐
Parameters sendobj (list[Any])
Return type list[Any]
Attributes Documentation ๐
degrees
Number of incoming and outgoing neighbors.
indegree
Number of incoming neighbors.
inedges
Incoming neighbors.
inoutedges
Incoming and outgoing neighbors.
outdegree
Number of outgoing neighbors.
outedges
Outgoing neighbors.
mpi4py.MPI.Win ๐
class mpi4py.MPI.Win
Bases: object
Remote memory access context. โจ (yes bestie, we're doing one-sided comms now, it's giving main character energy ๐)
static __new__(cls, win=None)
Parameters win (Win | None)
Return type Self
๐ซ Methods Summary ๐ซ
okay bestie, here's the whole roster of what a window object can do, and yes it's giving a lot of methods, but they're all one-sided communication baddies so let's get into it โจ
Accumulate(origin, target_rank[, target, op])โ Accumulate data into the target process. ๐ซถAllocate(size[, disp_unit, info, comm])โ Create an window object for one-sided communication.Allocate_shared(size[, disp_unit, info, comm])โ Create an window object for one-sided communication.Attach(memory)โ Attach a local memory region.Call_errhandler(errorcode)โ Call the error handler installed on a window.Compare_and_swap(origin, compare, result, ...)โ Perform one-sided atomic compare-and-swap. ๐ฅComplete()โ Complete an RMA operation begun after an Start.Create(memory[, disp_unit, info, comm])โ Create an window object for one-sided communication.Create_dynamic([info, comm])โ Create an window object for one-sided communication.Create_errhandler(errhandler_fn)โ Create a new error handler for windows.Create_keyval([copy_fn, delete_fn, nopython])โ Create a new attribute key for windows.Delete_attr(keyval)โ Delete attribute value associated with a key.Detach(memory)โ Detach a local memory region.Fence([assertion])โ Perform an MPI fence synchronization on a window. ๐งFetch_and_op(origin, result, target_rank[, ...])โ Perform one-sided read-modify-write.Flush(rank)โ Complete all outstanding RMA operations at a target.Flush_all()โ Complete all outstanding RMA operations at all targets.Flush_local(rank)โ Complete locally all outstanding RMA operations at a target.Flush_local_all()โ Complete locally all outstanding RMA operations at all targets.Free()โ Free a window.Free_keyval(keyval)โ Free an attribute key for windows.Get(origin, target_rank[, target])โ Get data from a memory window on a remote process. ๐Get_accumulate(origin, result, target_rank)โ Fetch-and-accumulate data into the target process.Get_attr(keyval)โ Retrieve attribute value by key.Get_errhandler()โ Get the error handler for a window.Get_group()โ Access the group of processes that created the window.Get_info()โ Return the current hints for a window.Get_name()โ Get the print name for this window.Lock(rank[, lock_type, assertion])โ Begin an RMA access epoch at the target process. ๐
okay so the Win method menu does not stop, bestie โ here's the second half of the alphabet, all the R's and S's plus the little utility girlies chilling at the bottom. every single one, no skips, no cap ๐
Lock_all([assertion])โ kick off an RMA access epoch at all the processes at once. not one, not a few โ everybody. group blast energy ๐Post(group[, assertion])โ start an RMA exposure epoch. this is you saying "i'm open for business" โจPut(origin, target_rank[, target])โ put data into a memory window living on a remote process. yeet it over there ๐ซถRaccumulate(origin, target_rank[, target, op])โ fetch-<em>and</em>-accumulate data into the target process. so it grabs the value and adds to it, one move, iconic ๐Rget(origin, target_rank[, target])โ get data from a memory window on a remote process. reaching across the network and snatching it, respectfully ๐Rget_accumulate(origin, result, target_rank)โ accumulate data into the target process using remote memory access ๐ฅRput(origin, target_rank[, target])โ put data into a memory window on a remote process. yes it's basicallyPut's twin, and yes they're both here, the docs said so ๐ธSet_attr(keyval, attrval)โ store an attribute value that's tied to a key. lil storage locker, but for attributes ๐Set_errhandler(errhandler)โ set the error handler for a window. choose who catches the chaos when things go sideways ๐Set_info(info)โ set new values for the hints associated with a window. hint glow-up โจSet_name(name)โ set the print name for this window. name your baby ๐Shared_query(rank)โ query the process-local address for remote memory segments. "where does that live on <em>my</em> side?" ๐Start(group[, assertion])โ start an RMA access epoch for MPI ๐ฆSync()โ synchronize the public and private copies of the window. get them on the same page, fr fr ๐ซถTest()โ test whether an RMA exposure epoch has completed. non-blocking vibe check, it just tells you yes or no ๐Unlock(rank)โ complete an RMA access epoch at the target process. wrap it up, we're done here ๐Unlock_all()โ complete an RMA access epoch at all processes. same energy, but for everybody at once ๐Wait()โ complete an RMA exposure epoch begun withPost. the patient sibling ofTestโญf2py(arg)โ the docs literally leave the description blank here, bestie. no tea, no crumbs, we don't invent ๐free()โ callFreeif not null. polite little cleanup moment ๐งนfromhandle(handle)โ create an object from an MPI handle ๐fromint(arg, /)โ translate an integer handle to an object. numbers to objects, glow-up complete โจpy2f()โ also blank in the docs. an enigma, a mystery, a girl who says nothing ๐ญtoint()โ translate an object to an integer handle. the reverse magic trick ๐ชtomemory()โ return window memory buffer. hand it over, we're taking it ๐
and that's the whole table wrapped, but the page is so not done yet โ keep scrolling, we're still going ๐
๐ Attributes Summary ๐
okay bestie, here's the quick lil vibe check on what attributes a Win is carrying around:
attrsโ Attributes.flavorโ Create flavor.groupโ Group.group_rankโ Group rank.group_sizeโ Group size.handleโ MPI handle.infoโ Info hints.modelโ Memory model.nameโ Print name.
๐ธ Methods Documentation ๐ธ
Accumulate(origin, target_rank, target=None, op=SUM)
Accumulate data into the target process. fr fr, you're dumping your data into somebody else's spot.
Parameters
origin(BufSpec)target_rank(int)target(TargetSpec|None)op(Op)
Return type
None
classmethod Allocate(size, disp_unit=1, info=INFO_NULL, comm=COMM_SELF)
Create an window object for one-sided communication. (yes bestie, the manpage itself said "an window", we don't fix, we respect ๐ )
Parameters
size(int)disp_unit(int)info(Info)comm(Intracomm)
Return type
Self
classmethod Allocate_shared(size, disp_unit=1, info=INFO_NULL, comm=COMM_SELF)
Create an window object for one-sided communication. shared edition, so everybody's on the same page literally.
Parameters
size(int)disp_unit(int)info(Info)comm(Intracomm)
Return type
Self
Attach(memory)
Attach a local memory region. plugging your lil memory chunk in, iconic.
Parameters
memory(Buffer)
Return type
None
Call_errhandler(errorcode)
Call the error handler installed on a window. yep, you're summoning the error handler.
Parameters
errorcode(int)
Return type
None
Compare_and_swap(origin, compare, result, target_rank, target_disp=0)
Perform one-sided atomic compare-and-swap. the atomic part is the โจ moment โจ, no cap.
Parameters
origin(BufSpec)compare(BufSpec)result(BufSpec)target_rank(int)target_disp(int)
Return type
None
Complete()
Complete an RMA operation begun after an Start. closing the loop on your started RMA era.
Return type
None
classmethod Create(memory, disp_unit=1, info=INFO_NULL, comm=COMM_SELF)
Create an window object for one-sided communication. the main character window-maker tbh.
Parameters
memory(Buffer|Bottom)disp_unit(int)info(Info)comm(Intracomm)
Return type
Self
classmethod Create_dynamic(info=INFO_NULL, comm=COMM_SELF)
Create an window object for one-sided communication. dynamic flavor, keeping it flexible.
Parameters
info(Info)comm(Intracomm)
Return type
Self
classmethod Create_errhandler(errhandler_fn)
Create a new error handler for windows. building your own lil safety net, we love to see it.
Parameters
errhandler_fn(Callable[[Win,int],None])
Return type
Errhandler
classmethod Create_keyval(copy_fn=None, delete_fn=None, nopython=False)
Create a new attribute key for windows. your custom key era begins now ๐
Parameters
copy_fn(Callable[[Win,int,Any],Any] |None)delete_fn(Callable[[Win,int,Any],None] |None)nopython(bool)
Return type
int
Delete_attr(keyval)
Delete attribute value associated with a key. bye bye attribute, we hardly knew ye.
Parameters
keyval(int)
Return type
None
Detach(memory)
Detach a local memory region. unplugging that memory chunk, respectfully.
Parameters
memory(Buffer)
Return type
None
Fence(assertion=0)
Perform an MPI fence synchronization on a window. everyone sync up besties ๐ง
Parameters
assertion(int)
Return type
None
Fetch_and_op(origin, result, target_rank, target_disp=0, op=SUM)
Perform one-sided read-modify-write. grab it, tweak it, put it back, one trip.
Parameters
origin(BufSpec)result(BufSpec)target_rank(int)target_disp(int)op(Op)
Return type
None
Flush(rank)
Complete all outstanding RMA operations at a target. clearing out the queue at that rank, no leftovers.
Parameters
rank(int)
Return type
None
Flush_all()
okay bestie, this one means complete all outstanding RMA operations at all targets. Like, every single one, everywhere. no stragglers. ๐
Return type: None
Flush_local(rank)
Complete locally all outstanding RMA operations at a target. the "locally" is doing a lot of work there, so read it carefully fr fr ๐ซถ
Parameters:
rank(int)
Return type: None
Flush_local_all()
Complete locally all outstanding RMA operations at all targets. same energy as Flush_local but it's giving "everyone at once". โจ
Return type: None
Free()
Free a window. that's it, that's the whole vibe. window freed, slay. ๐
Return type: None
classmethod Free_keyval(keyval)
Free an attribute key for windows. this is a classmethod, don't forget, it's not an instance situation. ๐
Parameters:
keyval(int)
Return type: int
Get(origin, target_rank, target=None)
Get data from a memory window on a remote process. it's a get. from remote memory. you're welcome. ๐
Parameters:
origin(BufSpec)target_rank(int)target(TargetSpec|None)
Return type: None
Get_accumulate(origin, result, target_rank, target=None, op=SUM)
Fetch-and-accumulate data into the target process. yes it does both things, that's the whole point of the name bestie, no cap. ๐ฅ
Parameters:
origin(BufSpec)result(BufSpec)target_rank(int)target(TargetSpec|None)op(Op) โ default isSUM
Return type: None
Get_attr(keyval)
Retrieve attribute value by key. give it the key, get the value back. iconic behaviour honestly. ๐
Parameters:
keyval(int)
Return type: int | Any | None
Get_errhandler()
Get the error handler for a window.
Return type: Errhandler
Get_group()
Access the group of processes that created the window. the whole little crew that made this window happen ๐ซถ
Return type: Group
Get_info()
Return the current hints for a window.
Return type: Info
Get_name()
Get the print name for this window. every window deserves a name, lowkey. ๐ธ
Return type: str
Lock(rank, lock_type=LOCK_EXCLUSIVE, assertion=0)
Begin an RMA access epoch at the target process. note the defaults, they're doing work here: lock_type defaults to LOCK_EXCLUSIVE and assertion defaults to 0. ๐
Parameters:
rank(int)lock_type(int)assertion(int)
Return type: None
Lock_all(assertion=0)
Begin an RMA access epoch at all processes. all of them. the whole group chat. โจ
Parameters:
assertion(int) โ default0
Return type: None
Post(group, assertion=0)
Start an RMA exposure epoch. yes "exposure epoch", that's the actual name, I don't make the rules. ๐
Parameters:
group(Group)assertion(int) โ default0
Return type: None
Put(origin, target_rank, target=None)
Put data into a memory window on a remote process. it's a put. into remote memory. as advertised. ๐
Parameters:
origin(BufSpec)target_rank(int)target(TargetSpec|None)
Return type: None
Raccumulate(origin, target_rank, target=None, op=SUM)
Fetch-and-accumulate data into the target process. the R up front means it's the nonblocking version and you get a Request back, bestie. ๐ฅ
Parameters:
origin(BufSpec)target_rank(int)target(TargetSpec|None)op(Op) โ default isSUM
Return type: Request
Rget(origin, target_rank, target=None)
Get data from a memory window on a remote process. again, but nonblocking this time, hence the R and the Request. ๐ฆ
Parameters:
origin(BufSpec)target_rank(int)target(TargetSpec|None)
Return type: Request
Rget_accumulate(origin, result, target_rank, target=None, op=SUM)
Accumulate data into the target process using remote memory access. yes it's the nonblocking one, and yes you get a Request. โจ
Parameters:
origin(BufSpec)result(BufSpec)target_rank(int)target(TargetSpec|None)op(Op) โ default isSUM
Return type: Request
Rput(origin, target_rank, target=None)
Put data into a memory window on a remote process. nonblocking put, Request back, you know the drill by now fr fr. ๐
Parameters:
origin(BufSpec)target_rank(int)target(TargetSpec|None)
Return type: Request
Set_attr(keyval, attrval)
Store attribute value associated with a key. give it a key AND a value, both are required, don't be shy. ๐
Parameters:
keyval(int)attrval(Any)
Return type: None
Set_errhandler(errhandler)
Set the error handler for a window.
Parameters:
errhandler(Errhandler)
Return type: None
Set_info(info)
Set new values for the hints associated with a window.
Parameters:
info(Info)
Return type: None
Set_name(name)
Set the print name for this window. go on, name it something cute. ๐ธ
Parameters:
name(str)
Return type: None
Shared_query(rank)
Query the process-local address for remote memory segments.
Parameters:
rank(int)
Return type: tuple[buffer, int] โ yeah bestie, a tuple, one buffer and one int, that's the whole vibe ๐ซ
Start(group, assertion=0)
Kick off an RMA access epoch for MPI. Go time ๐
Parameters
- group (
Group) โ the crew you're opening the epoch with - assertion (
int) โ your little hint to the implementation, no cap
Return type: None
Sync()
Synchronize the public and private copies of the window. Making them match, like matching outfits fr fr ๐
Return type: None
Test()
Test whether an RMA exposure epoch has completed. Just checking in ๐
Return type: bool
Unlock(rank)
Complete an RMA access epoch at the target process. Say bye to that one rank ๐
Parameters
- rank (
int)
Return type: None
Unlock_all()
Complete an RMA access epoch at all processes. Group hug, everyone's dismissed ๐ซถ
Return type: None
Wait()
Complete an RMA exposure epoch begun with Post. Sit there and wait for it to wrap up, main character patience energy โจ
Return type: Literal[True]
classmethod f2py(arg)
Parameters
- arg (
int)
Return type: Win
free()
Call Free if not null. Only nukes it when there's actually something to nuke ๐
Return type: None
classmethod fromhandle(handle)
Create object from MPI handle. Turning a raw handle into a whole object, it's giving glow-up ๐
Parameters
- handle (
int)
Return type: Win
classmethod fromint(arg, /)
Translate integer handle to object.
Parameters
- arg (
int)
Return type: Win
py2f()
Return type: int
toint()
Translate object to integer handle. Python side โ integer side, the classic handoff ๐
Return type: int
tomemory()
Return window memory buffer.
Return type: buffer
โจ Attributes Documentation โจ
attrsโ Attributes.flavorโ Create flavor.groupโ Group.group_rankโ Group rank.group_sizeโ Group size.handleโ MPI handle.infoโ Info hints.modelโ Memory model.nameโ Print name.
๐ซง mpi4py.MPI.buffer ๐ซง
class mpi4py.MPI.buffer
Bases: object
Buffer. That's it, that's the whole description, iconic brevity ๐
static __new__(cls, buf, /)
Parameters
- buf (
Buffer)
Return type: Self
๐ Methods Summary
allocate(nbytes[, clear])โ Buffer allocation.cast(format[, shape])โ Cast to amemoryviewwith new format or shape.fromaddress(address, nbytes[, readonly])โ Buffer from address and size in bytes.frombuffer(obj[, readonly])โ Buffer from buffer-like object.release()โ Release the underlying buffer exposed by the buffer object.tobytes([order])โ Return the data in the buffer as a byte string.toreadonly()โ Return a readonly version of the buffer object.
๐ Attributes Summary
addressโ Buffer address.formatโ Format of each element.itemsizeโ Size (in bytes) of each element.nbytesโ Buffer size (in bytes).objโ Object exposing buffer.readonlyโ Buffer is read-only.
๐ ๏ธ Methods Documentation ๐ ๏ธ
static allocate(nbytes, clear=False)
Buffer allocation. Fresh buffer, freshly allocated, periodt ๐
Parameters
- nbytes (
int) - clear (
bool)
Return type: buffer
cast(format, shape=Ellipsis)
Cast to a memoryview with new format or shape. Reinterpreting the whole thing, it's giving new outfit same person ๐
Parameters
- format (
str) - shape (
list[int] |tuple[int, ...])
Return type: memoryview
static fromaddress(address, nbytes, readonly=False)
Buffer from address and size in bytes. You bring the address, it brings the bytes ๐ง
Parameters
- address (
int) - nbytes (
int) - readonly (
bool)
Return type: buffer
static frombuffer(obj, readonly=False)
Buffer from buffer-like object. If it quacks like a buffer, it's a buffer ๐
Parameters
- obj (
Buffer) - readonly (
bool)
Return type: buffer
release()
Release the underlying buffer exposed by the buffer object.
Return type: None (<https://docs.python.org/3/library/constants.html#None>)
okay bestie, we're still deep in the buffer zone and it's giving immaculate โจ. Let's keep it moving, no cap.
tobytes(order=None)
This one hands you the data sitting in the buffer as a byte string. It's literally just bytes, fr fr. ๐
Parameters:
order(str(<https://docs.python.org/3/library/stdtypes.html#str>) |None(<https://docs.python.org/3/library/constants.html#None>))
Return type: bytes (<https://docs.python.org/3/library/stdtypes.html#bytes>)
toreadonly()
Returns a readonly version of the buffer object. Same vibe, but you can't touch it. ๐
Return type: buffer (<#mpi4py.MPI.buffer>)
Attributes Documentation
Here are the attributes, and every single one is iconic in its own way:
addressโ Buffer address. ๐formatโ Format of each element. ๐itemsizeโ Size (in bytes) of each element. ๐nbytesโ Buffer size (in bytes). ๐ฆobjโ Object exposing buffer. ๐ซถreadonlyโ Buffer is read-only. ๐
mpi4py.MPI.memory
mpi4py.MPI.memory โ alias of buffer (<#mpi4py.MPI.buffer>). It's literally the same thing, just a different name. Slay. โจ
Exceptions
Exception(<#mpi4py.MPI.Exception>) โ Exception class. ๐
mpi4py.MPI.Exception
exception mpi4py.MPI.Exception
Bases: RuntimeError (<https://docs.python.org/3/library/exceptions.html#RuntimeError>)
Exception class. It's the main character of error handling. ๐
__init__(ierr=SUCCESS, /)
Parameters:
ierr(int(<https://docs.python.org/3/library/functions.html#int>))
Return type: None (<https://docs.python.org/3/library/constants.html#None>)
Methods Summary
Get_error_class()โ Error class.Get_error_code()โ Error code.Get_error_string()โ Error string.
Attributes Summary
error_classโ Error class.error_codeโ Error code.error_stringโ Error string.
Methods Documentation
Get_error_class()
Error class.
Return type: int (<https://docs.python.org/3/library/functions.html#int>)
Get_error_code()
Error code.
Return type: int (<https://docs.python.org/3/library/functions.html#int>)
Get_error_string()
Error string.
Return type: str (<https://docs.python.org/3/library/stdtypes.html#str>)
Attributes Documentation
error_classโ Error class.error_codeโ Error code.error_stringโ Error string.
โจ Functions โจ
okay bestie, here's the whole roster of module-level functions hanging out in mpi4py.MPI โ the little global helpers that make the MPI world go round ๐ซถ read them like a contact list, because that's basically what they are.
Add_error_class()โ adds a brand-new error class to the pile of error classes everyone already knows about โจAdd_error_code(errorclass)โ tacks an error code onto a specific error class, like adding a new sticker to the collection ๐Add_error_string(errorcode, string)โ pairs an error string with either an error class or an error code, so the error actually has something to say ๐ฌAint_add(base, disp)โ hands you back the sum of the base address and the displacement. math but for pointers ๐งฎAint_diff(addr1, addr2)โ gives you the difference between two absolute addresses, lowkey just subtraction with aura ๐Alloc_mem(size[, info])โ allocates memory meant for message passing and remote memory access. it's giving malloc but make it MPI ๐Attach_buffer(buf)โ attaches a buffer you provided so stuff can be sent in buffered mode. your buffer, your rules ๐Close_port(port_name)โ closes a port. that's it, that's the tweet ๐Compute_dims(nnodes, dims)โ returns a balanced distribution of processes across each coordinate direction. perfectly balanced, as all things should be โ๏ธDetach_buffer()โ removes an attached buffer that's currently attached. bye bestie ๐Finalize()โ terminates the MPI execution environment. the grand finale, the last bow ๐ญFlush_buffer()โ blocks until every single buffered message has actually been transmitted. sit there and wait, no skipping the queue โณFree_mem(mem)โ frees memory that was allocated withAlloc_mem. whatAlloc_memgiveth,Free_memtaketh away ๐งนGet_abi_fortran_info()โ obtains information about the Fortran MPI ABI. fortran girlies, this one's for you ๐ธGet_abi_info()โ obtains information about the MPI ABI ๐Get_abi_version()โ obtains the MPI ABI version number. numbers, iconic ๐ขGet_address(location)โ gets the address of a location in memory. pointing at things, professionally ๐Get_error_class(errorcode)โ converts an error code into an error class ๐Get_error_string(errorcode)โ returns the error string for a given error class or error code. it explains itself, we love a self-aware function ๐Get_hw_resource_info()โ obtains information about the hardware platform of the processor doing the calling ๐ฅ๏ธโจGet_library_version()โ obtains the version string of the MPI library. version check, as always ๐Get_processor_name()โ obtains the name of the processor that's calling. hi, what's your name ๐คGet_version()โ obtains the version number of the MPI standard ๐Iflush_buffer()โ nonblocking flush for buffered messages. same energy asFlush_bufferbut it does not wait around for you ๐โโ๏ธInit()โ initializes the MPI execution environment. the beginning of everything ๐Init_thread([required])โ initializes the MPI execution environment, thread edition ๐งตIs_finalized()โ indicates whetherFinalizehas completed. yes or no, no in-between ๐ฏIs_initialized()โ indicates whetherInithas been called โIs_thread_main()โ indicates whether this thread is the one that calledInitorInit_thread. main character check ๐
the way that half of these are just "initialize this" and "is it initialized yet"โฆ the lore is consistent at least ๐ญ
okay bestie we're still deep in the roster scroll, no context switch, just vibes and functions ๐ continuing the lineup:
Lookup_name <#mpi4py.MPI.Lookup_name>(service_name[, info])โ looks up a port name given a service name โจOpen_port <#mpi4py.MPI.Open_port>([info])โ returns an address you use to connect a group of processes ๐ซถPcontrol <#mpi4py.MPI.Pcontrol>(level)โ controls profiling, literally just that ๐ธPublish_name <#mpi4py.MPI.Publish_name>(service_name, port_name[, info])โ publishes a service name ๐ฃQuery_thread <#mpi4py.MPI.Query_thread>()โ hands you back the level of thread support the MPI library is providing ๐งตRegister_datarep <#mpi4py.MPI.Register_datarep>(datarep, read_fn, write_fn, ...)โ registers user-defined data representations ๐Remove_error_class <#mpi4py.MPI.Remove_error_class>(errorclass)โ removes an error class from the known error classes ๐๏ธRemove_error_code <#mpi4py.MPI.Remove_error_code>(errorcode)โ removes an error code from the known error codesRemove_error_string <#mpi4py.MPI.Remove_error_string>(errorcode)โ removes the error string association from an error class or error codeUnpublish_name <#mpi4py.MPI.Unpublish_name>(service_name, port_name[, info])โ unpublishes a service name, off the shelf it goesWtick <#mpi4py.MPI.Wtick>()โ returns the resolution ofWtime <#mpi4py.MPI.Wtime>โฑ๏ธWtime <#mpi4py.MPI.Wtime>()โ returns an elapsed time on the calling processorget_vendor <#mpi4py.MPI.get_vendor>()โ information about the underlying MPI implementation ๐
mpi4py.MPI.Add_error_class
mpi4py.MPI.Add_error_class()
Adds an error class to the known error classes. lowkey essential ๐
Return type: int <https://docs.python.org/3/library/functions.html#int>
mpi4py.MPI.Add_error_code
mpi4py.MPI.Add_error_code(errorclass)
Adds an error code to an error class ๐
Parameters:
- errorclass (
int <https://docs.python.org/3/library/functions.html#int>)
Return type: int <https://docs.python.org/3/library/functions.html#int>
mpi4py.MPI.Add_error_string
mpi4py.MPI.Add_error_string(errorcode, string)
Associates an error string with an error class or an error code ๐ธ
Parameters:
- errorcode (
int <https://docs.python.org/3/library/functions.html#int>) - string (
str <https://docs.python.org/3/library/stdtypes.html#str>)
Return type: None <https://docs.python.org/3/library/constants.html#None>
mpi4py.MPI.Aint_add
mpi4py.MPI.Aint_add(base, disp)
Returns the sum of base address and displacement ๐งฎ
Parameters:
- base (
int <https://docs.python.org/3/library/functions.html#int>) - disp (
int <https://docs.python.org/3/library/functions.html#int>)
Return type: int <https://docs.python.org/3/library/functions.html#int>
mpi4py.MPI.Aint_diff
mpi4py.MPI.Aint_diff(addr1, addr2)
Returns the difference between absolute addresses ๐
Parameters:
- addr1 (
int <https://docs.python.org/3/library/functions.html#int>) - addr2 (
int <https://docs.python.org/3/library/functions.html#int>)
Return type: int <https://docs.python.org/3/library/functions.html#int>
mpi4py.MPI.Alloc_mem
mpi4py.MPI.Alloc_mem(size, info=INFO_NULL)
Allocates memory for message passing and remote memory access ๐ซถ
Parameters:
- size (
int <https://docs.python.org/3/library/functions.html#int>) - info (
Info <#mpi4py.MPI.Info>)
Return type: buffer <#mpi4py.MPI.buffer>
mpi4py.MPI.Attach_buffer
mpi4py.MPI.Attach_buffer(buf)
Attaches a user-provided buffer for sending in buffered mode ๐ฆ
Parameters:
- buf (
Buffer <#mpi4py.typing.Buffer>|None <https://docs.python.org/3/library/constants.html#None>)
Return type: None <https://docs.python.org/3/library/constants.html#None>
mpi4py.MPI.Close_port
mpi4py.MPI.Close_port(port_name)
Closes a port ๐ช
Parameters:
- port_name (
str <https://docs.python.org/3/library/stdtypes.html#str>)
Return type: None <https://docs.python.org/3/library/constants.html#None>
mpi4py.MPI.Compute_dims
mpi4py.MPI.Compute_dims(nnodes, dims)
Returns a balanced distribution of processes per coordinate direction โ๏ธ
Parameters:
- nnodes (
int <https://docs.python.org/3/library/functions.html#int>) - dims (
int <https://docs.python.org/3/library/functions.html#int>|Sequence <https://docs.python.org/3/library/typing.html#typing.Sequence>[int <https://docs.python.org/3/library/functions.html#int>])
Return type: list <https://docs.python.org/3/library/stdtypes.html#list>[int <https://docs.python.org/3/library/functions.html#int>]
mpi4py.MPI.Detach_buffer
mpi4py.MPI.Detach_buffer()
Removes an existing attached buffer ๐๏ธ
Return type: Buffer <#mpi4py.typing.Buffer> | None <https://docs.python.org/3/library/constants.html#None>
mpi4py.MPI.Finalize
mpi4py.MPI.Finalize()
Terminates the MPI execution environment ๐
Return type: None <https://docs.python.org/3/library/constants.html#None>
mpi4py.MPI.Flush_buffer
mpi4py.MPI.Flush_buffer()
Blocks until all buffered messages have been transmitted ๐ฐ
Return type: None <https://docs.python.org/3/library/constants.html#None>
mpi4py.MPI.Free_mem
mpi4py.MPI.Free_mem(mem)
Frees memory allocated with Alloc_mem <#mpi4py.MPI.Alloc_mem> ๐งน
Parameters:
- mem (
buffer <#mpi4py.MPI.buffer>)
Return type: None <https://docs.python.org/3/library/constants.html#None>
mpi4py.MPI.Get_abi_fortran_info
mpi4py.MPI.Get_abi_fortran_info()
Obtains information about the Fortran MPI ABI ๐ง
Return type: Info <#mpi4py.MPI.Info>
mpi4py.MPI.Get_abi_info
mpi4py.MPI.Get_abi_info()
Obtains information about the MPI ABI ๐
Return type: Info <#mpi4py.MPI.Info>
mpi4py.MPI.Get_abi_version
mpi4py.MPI.Get_abi_version()
Obtains the MPI ABI version number ๐ข
Return type: tuple <https://docs.python.org/3/library/stdtypes.html#tuple>[int <https://docs.python.org/3/library/functions.html#int>, int <https://docs.python.org/3/library/functions.html#int>]
mpi4py.MPI.Get_address
mpi4py.MPI.Get_address(location)
okay so this one is literally just: hand it a location and it tells you the address of that spot in memory. that's it, that's the whole vibe โจ
locationโBuffer|Bottom
Returns โ int ๐
mpi4py.MPI.Get_error_class
mpi4py.MPI.Get_error_class(errorcode)
take an error code and translate it into its error class, bestie. glow-up for error codes ๐
errorcodeโint
Returns โ int
mpi4py.MPI.Get_error_string
mpi4py.MPI.Get_error_string(errorcode)
give me the words!! this hands you the error string for whatever error class or error code you pass in. so you can actually read what went wrong instead of staring at a number like ๐ญ
errorcodeโint
Returns โ str
mpi4py.MPI.Get_hw_resource_info
mpi4py.MPI.Get_hw_resource_info()
no arguments, no stress. it pulls info about the hardware platform of the processor that's calling it. hardware lore ๐ฅ
Returns โ Info
mpi4py.MPI.Get_library_version
mpi4py.MPI.Get_library_version()
gets you the version string of the MPI library. version check era ๐
Returns โ str
mpi4py.MPI.Get_processor_name
mpi4py.MPI.Get_processor_name()
asks the calling processor for its name. yes it knows its own name, it's that girl ๐ธ
Returns โ str
mpi4py.MPI.Get_version
mpi4py.MPI.Get_version()
version number of the MPI standard itself. note: it comes back as a tuple of two ints, not a string, so don't @ me ๐
Returns โ tuple[int, int]
mpi4py.MPI.Iflush_buffer
mpi4py.MPI.Iflush_buffer()
nonblocking flush for buffered messages. yes, nonblocking, meaning it does not wait around for you โ it hands you a Request and dips ๐ฆ
Returns โ Request
mpi4py.MPI.Init
mpi4py.MPI.Init()
the big one. initializes the MPI execution environment. like, the whole thing doesn't work without this. main character energy fr fr โจ
Returns โ None
mpi4py.MPI.Init_thread
mpi4py.MPI.Init_thread(required=THREAD_MULTIPLE)
also initializes the MPI execution environment, but make it threaded ๐งต the required arg defaults to THREAD_MULTIPLE, which is highkey the most you can ask for.
requiredโint
Returns โ int
mpi4py.MPI.Is_finalized
mpi4py.MPI.Is_finalized()
tells you whether Finalize has finished yet. a bool, no drama ๐
Returns โ bool
mpi4py.MPI.Is_initialized
mpi4py.MPI.Is_initialized()
tells you whether Init has been called. vibe check on your own setup ๐
Returns โ bool
mpi4py.MPI.Is_thread_main
mpi4py.MPI.Is_thread_main()
asking the real questions: did this thread call Init or Init_thread? if yes, you're the main character. if noโฆ still valid ๐
Returns โ bool
mpi4py.MPI.Lookup_name
mpi4py.MPI.Lookup_name(service_name, info=INFO_NULL)
looks up a port name when you give it a service name. the info argument defaults to INFO_NULL, so it's optional, chill ๐ซถ
service_nameโstrinfoโInfo(defaults toINFO_NULL)
Returns โ str
mpi4py.MPI.Open_port
mpi4py.MPI.Open_port(info=INFO_NULL)
returns an address you can use to connect a whole group of processes together. very "let's get the group chat going" ๐
infoโInfo(defaults toINFO_NULL)
Returns โ str
mpi4py.MPI.Pcontrol
mpi4py.MPI.Pcontrol(level)
controls profiling. that's the whole description, I'm not gonna invent lore for it ๐ญ
levelโint
Returns โ None
mpi4py.MPI.Publish_name
mpi4py.MPI.Publish_name(service_name, port_name, info=INFO_NULL)
publishes a service name โ so other processes can find it. info again defaults to INFO_NULL โจ
service_nameโstrport_nameโstrinfoโInfo(defaults toINFO_NULL)
Returns โ None
mpi4py.MPI.Query_thread
mpi4py.MPI.Query_thread()
returns the level of thread support the MPI library is actually giving you. not what you asked for โ what you got ๐
Returns โ int
mpi4py.MPI.Register_datarep
mpi4py.MPI.Register_datarep(datarep, read_fn, write_fn, extent_fn)
register your own user-defined data representations. very DIY, very craft-core ๐
datarepโstrread_fnโCallable[[Buffer, Datatype, int, Buffer, int], None]write_fnโCallable[[Buffer, Datatype, int, Buffer, int], None]extent_fnโCallable[[Datatype], int]
Returns โ None
mpi4py.MPI.Remove_error_class
mpi4py.MPI.Remove_error_class(errorclass)
un-registers an error class from the known error classes. bye bestie ๐
errorclassโint
Returns โ None
mpi4py.MPI.Remove_error_code
mpi4py.MPI.Remove_error_code(errorcode)
same energy, different target: removes an error code from the known error codes ๐
errorcodeโint
Returns โ None
mpi4py.MPI.Remove_error_string
mpi4py.MPI.Remove_error_string(errorcode)
breaks up the error string + error class/code association. it's giving "we're not together anymore" ๐ญ
errorcodeโint
Returns โ None
mpi4py.MPI.Unpublish_name
mpi4py.MPI.Unpublish_name(service_name, port_name, info=INFO_NULL)
unpublishes a service name. the reverse of Publish_name, obviously, iconic symmetry โจ
service_nameโstrport_nameโstrinfoโInfo(defaults toINFO_NULL)
Returns โ None
mpi4py.MPI.Wtick
mpi4py.MPI.Wtick()
tells you the resolution of Wtime. so you know how fine-grained your clock reading actually is โฑ๏ธ
Returns โ float
mpi4py.MPI.Wtime
mpi4py.MPI.Wtime()
returns an elapsed time on the calling processor. your basic clock read, no cap ๐
Returns โ float
mpi4py.MPI.get_vendor
mpi4py.MPI.get_vendor()
the gossip function!! tells you about the underlying MPI implementation you're actually running on ๐
Returns:
- a
stringwith the name of the MPI implementation. - an integer 3-tuple version number
(major, minor, micro).
Returns โ tuple[str, tuple[int, int, int]]
so you get the name and the numbers, together, as a tuple. slay ๐ซถ
โจ Attributes โจ
okay bestie, gather round, because here's the whole vibe check on the attributes. every single one is a constant, and every single one is type int. no cap. let's go ๐
UNDEFINED(#mpi4py.MPI.UNDEFINED) โ ConstantUNDEFINEDof typeint(https://docs.python.org/3/library/functions.html#int). ๐ANY_SOURCE(#mpi4py.MPI.ANY_SOURCE) โ ConstantANY_SOURCEof typeint(https://docs.python.org/3/library/functions.html#int). โจANY_TAG(#mpi4py.MPI.ANY_TAG) โ ConstantANY_TAGof typeint(https://docs.python.org/3/library/functions.html#int). ๐ฆPROC_NULL(#mpi4py.MPI.PROC_NULL) โ ConstantPROC_NULLof typeint(https://docs.python.org/3/library/functions.html#int). ๐ธROOT(#mpi4py.MPI.ROOT) โ ConstantROOTof typeint(https://docs.python.org/3/library/functions.html#int). ๐KEYVAL_INVALID(#mpi4py.MPI.KEYVAL_INVALID) โ ConstantKEYVAL_INVALIDof typeint(https://docs.python.org/3/library/functions.html#int). ๐ซถTAG_UB(#mpi4py.MPI.TAG_UB) โ ConstantTAG_UBof typeint(https://docs.python.org/3/library/functions.html#int). ๐ญIO(#mpi4py.MPI.IO) โ ConstantIOof typeint(https://docs.python.org/3/library/functions.html#int). ๐ฅWTIME_IS_GLOBAL(#mpi4py.MPI.WTIME_IS_GLOBAL) โ ConstantWTIME_IS_GLOBALof typeint(https://docs.python.org/3/library/functions.html#int). ๐UNIVERSE_SIZE(#mpi4py.MPI.UNIVERSE_SIZE) โ ConstantUNIVERSE_SIZEof typeint(https://docs.python.org/3/library/functions.html#int). ๐APPNUM(#mpi4py.MPI.APPNUM) โ ConstantAPPNUMof typeint(https://docs.python.org/3/library/functions.html#int). โญLASTUSEDCODE(#mpi4py.MPI.LASTUSEDCODE) โ ConstantLASTUSEDCODEof typeint(https://docs.python.org/3/library/functions.html#int). ๐WIN_BASE(#mpi4py.MPI.WIN_BASE) โ ConstantWIN_BASEof typeint(https://docs.python.org/3/library/functions.html#int). ๐WIN_SIZE(#mpi4py.MPI.WIN_SIZE) โ ConstantWIN_SIZEof typeint(https://docs.python.org/3/library/functions.html#int). ๐WIN_DISP_UNIT(#mpi4py.MPI.WIN_DISP_UNIT) โ ConstantWIN_DISP_UNITof typeint(https://docs.python.org/3/library/functions.html#int). ๐งWIN_CREATE_FLAVOR(#mpi4py.MPI.WIN_CREATE_FLAVOR) โ ConstantWIN_CREATE_FLAVORof typeint(https://docs.python.org/3/library/functions.html#int). ๐WIN_FLAVOR(#mpi4py.MPI.WIN_FLAVOR) โ ConstantWIN_FLAVORof typeint(https://docs.python.org/3/library/functions.html#int). ๐WIN_MODEL(#mpi4py.MPI.WIN_MODEL) โ ConstantWIN_MODELof typeint(https://docs.python.org/3/library/functions.html#int). โจSUCCESS(#mpi4py.MPI.SUCCESS) โ ConstantSUCCESSof typeint(https://docs.python.org/3/library/functions.html#int). ๐ฆERR_LASTCODE(#mpi4py.MPI.ERR_LASTCODE) โ ConstantERR_LASTCODEof typeint(https://docs.python.org/3/library/functions.html#int). ๐ธERR_ABI(#mpi4py.MPI.ERR_ABI) โ ConstantERR_ABIof typeint(https://docs.python.org/3/library/functions.html#int). ๐ERR_TYPE(#mpi4py.MPI.ERR_TYPE) โ ConstantERR_TYPEof typeint(https://docs.python.org/3/library/functions.html#int). ๐ซถERR_REQUEST(#mpi4py.MPI.ERR_REQUEST) โ ConstantERR_REQUESTof typeint(https://docs.python.org/3/library/functions.html#int). ๐ญ
okay bestie the error-constant parade is still going, don't unclench yet ๐
every single one of these is a lil named constant, and every single one is chillin' as an int <https://docs.python.org/3/library/functions.html#int> โ no cap, that's the whole vibe:
ERR_OP<#mpi4py.MPI.ERR_OP> โ ConstantERR_OP, typeint<https://docs.python.org/3/library/functions.html#int> โจERR_GROUP<#mpi4py.MPI.ERR_GROUP> โ ConstantERR_GROUP, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_INFO<#mpi4py.MPI.ERR_INFO> โ ConstantERR_INFO, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_ERRHANDLER<#mpi4py.MPI.ERR_ERRHANDLER> โ ConstantERR_ERRHANDLER, typeint<https://docs.python.org/3/library/functions.html#int> ๐ฆERR_SESSION<#mpi4py.MPI.ERR_SESSION> โ ConstantERR_SESSION, typeint<https://docs.python.org/3/library/functions.html#int> ๐ธERR_COMM<#mpi4py.MPI.ERR_COMM> โ ConstantERR_COMM, typeint<https://docs.python.org/3/library/functions.html#int> ๐ซถERR_WIN<#mpi4py.MPI.ERR_WIN> โ ConstantERR_WIN, typeint<https://docs.python.org/3/library/functions.html#int> ๐ญERR_FILE<#mpi4py.MPI.ERR_FILE> โ ConstantERR_FILE, typeint<https://docs.python.org/3/library/functions.html#int> ๐ฅERR_BUFFER<#mpi4py.MPI.ERR_BUFFER> โ ConstantERR_BUFFER, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_COUNT<#mpi4py.MPI.ERR_COUNT> โ ConstantERR_COUNT, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_TAG<#mpi4py.MPI.ERR_TAG> โ ConstantERR_TAG, typeint<https://docs.python.org/3/library/functions.html#int> โญERR_RANK<#mpi4py.MPI.ERR_RANK> โ ConstantERR_RANK, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_ROOT<#mpi4py.MPI.ERR_ROOT> โ ConstantERR_ROOT, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_TRUNCATE<#mpi4py.MPI.ERR_TRUNCATE> โ ConstantERR_TRUNCATE, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_IN_STATUS<#mpi4py.MPI.ERR_IN_STATUS> โ ConstantERR_IN_STATUS, typeint<https://docs.python.org/3/library/functions.html#int> ๐งERR_PENDING<#mpi4py.MPI.ERR_PENDING> โ ConstantERR_PENDING, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_TOPOLOGY<#mpi4py.MPI.ERR_TOPOLOGY> โ ConstantERR_TOPOLOGY, typeint<https://docs.python.org/3/library/functions.html#int> โจERR_DIMS<#mpi4py.MPI.ERR_DIMS> โ ConstantERR_DIMS, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_ARG<#mpi4py.MPI.ERR_ARG> โ ConstantERR_ARG, typeint<https://docs.python.org/3/library/functions.html#int> ๐ERR_OTHER<#mpi4py.MPI.ERR_OTHER> โ ConstantERR_OTHER, typeint<https://docs.python.org/3/library/functions.html#int> ๐ฆERR_UNKNOWN<#mpi4py.MPI.ERR_UNKNOWN> โ ConstantERR_UNKNOWN, typeint<https://docs.python.org/3/library/functions.html#int> ๐ธERR_INTERN<#mpi4py.MPI.ERR_INTERN> โ ConstantERR_INTERN, typeint<https://docs.python.org/3/library/functions.html#int> ๐ซถERR_KEYVAL<#mpi4py.MPI.ERR_KEYVAL> โ ConstantERR_KEYVAL, typeint<https://docs.python.org/3/library/functions.html#int> ๐ญ
and that's the whole block of error codes, each one anchored at its own lil spot <#mpi4py.MPI.ERR_KEYVAL>-style so you can jump straight to it, iykyk ๐ซถ
okay so we are still in the constants zone and it's giving โจint energyโจ โ every single one of these is a plain old int, no cap. here's the whole lineup, nothing skipped, nothing merged, we move ๐
ERR_NO_MEMโ anchor#mpi4py.MPI.ERR_NO_MEM. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_INFO_KEYโ anchor#mpi4py.MPI.ERR_INFO_KEY. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_INFO_VALUEโ anchor#mpi4py.MPI.ERR_INFO_VALUE. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_INFO_NOKEYโ anchor#mpi4py.MPI.ERR_INFO_NOKEY. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_SPAWNโ anchor#mpi4py.MPI.ERR_SPAWN. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_PORTโ anchor#mpi4py.MPI.ERR_PORT. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_SERVICEโ anchor#mpi4py.MPI.ERR_SERVICE. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_NAMEโ anchor#mpi4py.MPI.ERR_NAME. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_PROC_ABORTEDโ anchor#mpi4py.MPI.ERR_PROC_ABORTED. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_BASEโ anchor#mpi4py.MPI.ERR_BASE. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_SIZEโ anchor#mpi4py.MPI.ERR_SIZE. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_DISPโ anchor#mpi4py.MPI.ERR_DISP. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_ASSERTโ anchor#mpi4py.MPI.ERR_ASSERT. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_LOCKTYPEโ anchor#mpi4py.MPI.ERR_LOCKTYPE. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_RMA_CONFLICTโ anchor#mpi4py.MPI.ERR_RMA_CONFLICT. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_RMA_SYNCโ anchor#mpi4py.MPI.ERR_RMA_SYNC. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_RMA_RANGEโ anchor#mpi4py.MPI.ERR_RMA_RANGE. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_RMA_ATTACHโ anchor#mpi4py.MPI.ERR_RMA_ATTACH. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_RMA_SHAREDโ anchor#mpi4py.MPI.ERR_RMA_SHARED. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_RMA_FLAVORโ anchor#mpi4py.MPI.ERR_RMA_FLAVOR. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_BAD_FILEโ anchor#mpi4py.MPI.ERR_BAD_FILE. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_NO_SUCH_FILEโ anchor#mpi4py.MPI.ERR_NO_SUCH_FILE. constant, typeintโ https://docs.python.org/3/library/functions.html#intERR_FILE_EXISTSโ anchor#mpi4py.MPI.ERR_FILE_EXISTS. constant, typeintโ https://docs.python.org/3/library/functions.html#int
fr fr, that's the whole list โ if you were hoping for a surprise non-inttype in there, bestie, there isn't one ๐ญ every single constant above is typeintand that's the tea.
okay bestie we are STILL in the constants list and it is lowkey never-ending ๐ but every single one of these is an int โ the Python builtin int, fr (https://docs.python.org/3/library/functions.html#int) โ and each one has its own little anchor link. no skipping, we're doing all of them, periodt โจ
ERR_FILE_IN_USEโ constantERR_FILE_IN_USE, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_FILE_IN_USEERR_AMODEโ constantERR_AMODE, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_AMODEERR_ACCESSโ constantERR_ACCESS, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_ACCESSERR_READ_ONLYโ constantERR_READ_ONLY, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_READ_ONLYERR_NO_SPACEโ constantERR_NO_SPACE, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_NO_SPACEERR_QUOTAโ constantERR_QUOTA, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_QUOTAERR_NOT_SAMEโ constantERR_NOT_SAME, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_NOT_SAMEERR_IOโ constantERR_IO, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_IOERR_UNSUPPORTED_OPERATIONโ constantERR_UNSUPPORTED_OPERATION, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_UNSUPPORTED_OPERATIONERR_UNSUPPORTED_DATAREPโ constantERR_UNSUPPORTED_DATAREP, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_UNSUPPORTED_DATAREPERR_CONVERSIONโ constantERR_CONVERSION, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_CONVERSIONERR_DUP_DATAREPโ constantERR_DUP_DATAREP, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_DUP_DATAREPERR_VALUE_TOO_LARGEโ constantERR_VALUE_TOO_LARGE, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_VALUE_TOO_LARGEERR_REVOKEDโ constantERR_REVOKED, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_REVOKEDERR_PROC_FAILEDโ constantERR_PROC_FAILED, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_PROC_FAILEDERR_PROC_FAILED_PENDINGโ constantERR_PROC_FAILED_PENDING, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ERR_PROC_FAILED_PENDING
and now we glide on over from error codes into the ordering + typeclass constants, which are also all just ints, iconic honestly ๐
ORDER_Cโ constantORDER_C, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ORDER_CORDER_FORTRANโ constantORDER_FORTRAN, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ORDER_FORTRANORDER_Fโ constantORDER_F, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.ORDER_FTYPECLASS_LOGICALโ constantTYPECLASS_LOGICAL, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.TYPECLASS_LOGICALTYPECLASS_INTEGERโ constantTYPECLASS_INTEGER, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.TYPECLASS_INTEGERTYPECLASS_REALโ constantTYPECLASS_REAL, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.TYPECLASS_REALTYPECLASS_COMPLEXโ constantTYPECLASS_COMPLEX, of typeint(https://docs.python.org/3/library/functions.html#int). ๐ anchor:#mpi4py.MPI.TYPECLASS_COMPLEX
okay continuing the great constant parade bestie โจ we're still deep in the reference and this stretch is literally just a lineup of int values, no cap ๐
tiny PSA before we go: whenever it says "of type int" below, that's linking out to the Python docs at https://docs.python.org/3/library/functions.html#int โ same URL every single time, so I'm not retyping it twenty-three times, iykyk ๐
MPI.TYPECLASS_COMPLEXโ ConstantTYPECLASS_COMPLEXof typeint๐DISTRIBUTE_NONEโ ConstantDISTRIBUTE_NONEof typeint. distributing: declined ๐DISTRIBUTE_BLOCKโ ConstantDISTRIBUTE_BLOCKof typeint. block it out ๐งฑDISTRIBUTE_CYCLICโ ConstantDISTRIBUTE_CYCLICof typeint. round and round we go ๐DISTRIBUTE_DFLT_DARGโ ConstantDISTRIBUTE_DFLT_DARGof typeint๐ธCOMBINER_NAMEDโ ConstantCOMBINER_NAMEDof typeintโจCOMBINER_DUPโ ConstantCOMBINER_DUPof typeint๐ฆCOMBINER_CONTIGUOUSโ ConstantCOMBINER_CONTIGUOUSof typeint๐ฅCOMBINER_VECTORโ ConstantCOMBINER_VECTORof typeint๐COMBINER_HVECTORโ ConstantCOMBINER_HVECTORof typeint๐COMBINER_INDEXEDโ ConstantCOMBINER_INDEXEDof typeintโญCOMBINER_HINDEXEDโ ConstantCOMBINER_HINDEXEDof typeint๐COMBINER_INDEXED_BLOCKโ ConstantCOMBINER_INDEXED_BLOCKof typeint๐COMBINER_HINDEXED_BLOCKโ ConstantCOMBINER_HINDEXED_BLOCKof typeint๐COMBINER_STRUCTโ ConstantCOMBINER_STRUCTof typeint๐COMBINER_SUBARRAYโ ConstantCOMBINER_SUBARRAYof typeint๐งCOMBINER_DARRAYโ ConstantCOMBINER_DARRAYof typeint๐ธCOMBINER_RESIZEDโ ConstantCOMBINER_RESIZEDof typeint๐COMBINER_VALUE_INDEXโ ConstantCOMBINER_VALUE_INDEXof typeintโจCOMBINER_F90_INTEGERโ ConstantCOMBINER_F90_INTEGERof typeint๐ซถCOMBINER_F90_REALโ ConstantCOMBINER_F90_REALof typeint๐COMBINER_F90_COMPLEXโ ConstantCOMBINER_F90_COMPLEXof typeint๐F_SOURCEโ ConstantF_SOURCEof typeintโญ
and yeah that's where this part taps out, bestie โ more coming, don't you dare stop scrolling ๐
โฆand the constant parade just keeps going, bestie ๐ so real quick, before we list them: every single one of these is a plain int, no cap โ that's the only type situation happening here. The int docs live at https://docs.python.org/3/library/functions.html#int if you ever wanna peek, but honestly? It's giving "just vibes and integers." Periodt. ๐
F_TAGโ constantF_TAG, of typeintโจF_ERRORโ constantF_ERROR, of typeint๐F_STATUS_SIZEโ constantF_STATUS_SIZE, of typeint๐IDENTโ constantIDENT, of typeint๐ฆCONGRUENTโ constantCONGRUENT, of typeint๐ธSIMILARโ constantSIMILAR, of typeint๐UNEQUALโ constantUNEQUAL, of typeint๐ญCARTโ constantCART, of typeint๐ฅGRAPHโ constantGRAPH, of typeint๐DIST_GRAPHโ constantDIST_GRAPH, of typeint๐UNWEIGHTEDโ constantUNWEIGHTED, of typeintโญWEIGHTS_EMPTYโ constantWEIGHTS_EMPTY, of typeint๐COMM_TYPE_SHAREDโ constantCOMM_TYPE_SHARED, of typeint๐ซถCOMM_TYPE_HW_GUIDEDโ constantCOMM_TYPE_HW_GUIDED, of typeint๐งCOMM_TYPE_HW_UNGUIDEDโ constantCOMM_TYPE_HW_UNGUIDED, of typeint๐ซCOMM_TYPE_RESOURCE_GUIDEDโ constantCOMM_TYPE_RESOURCE_GUIDED, of typeint๐BSEND_OVERHEADโ constantBSEND_OVERHEAD, of typeint๐WIN_FLAVOR_CREATEโ constantWIN_FLAVOR_CREATE, of typeint๐WIN_FLAVOR_ALLOCATEโ constantWIN_FLAVOR_ALLOCATE, of typeint๐WIN_FLAVOR_DYNAMICโ constantWIN_FLAVOR_DYNAMIC, of typeintโจWIN_FLAVOR_SHAREDโ constantWIN_FLAVOR_SHARED, of typeint๐WIN_SEPARATEโ constantWIN_SEPARATE, of typeint๐ฆ
and that's the whole int-coded crew, bestie โ lowkey iconic of them to all show up looking exactly the same ๐ซถ keep scrolling, there's more where that came from ๐
okay bestie, we're still in the constant zone and there's a LOT of them, so let's keep it moving ๐
these are all just plain old constants, each one of type int (you know, the Python int situation), and they're all living their best life in mpi4py.MPI. no cap, that's the whole vibe of every single one:
WIN_UNIFIEDโ ConstantWIN_UNIFIED, and yes it's typeint๐ซถMODE_NOCHECKโ ConstantMODE_NOCHECK, typeintโจMODE_NOSTOREโ ConstantMODE_NOSTORE, typeintโจMODE_NOPUTโ ConstantMODE_NOPUT, typeintโจMODE_NOPRECEDEโ ConstantMODE_NOPRECEDE, typeintโจMODE_NOSUCCEEDโ ConstantMODE_NOSUCCEED, typeintโจLOCK_EXCLUSIVEโ ConstantLOCK_EXCLUSIVE, typeint๐LOCK_SHAREDโ ConstantLOCK_SHARED, typeint๐MODE_RDONLYโ ConstantMODE_RDONLY, typeint๐MODE_WRONLYโ ConstantMODE_WRONLY, typeintโ๏ธMODE_RDWRโ ConstantMODE_RDWR, typeint๐โ๏ธMODE_CREATEโ ConstantMODE_CREATE, typeint๐MODE_EXCLโ ConstantMODE_EXCL, typeint๐ซMODE_DELETE_ON_CLOSEโ ConstantMODE_DELETE_ON_CLOSE, typeint๐MODE_UNIQUE_OPENโ ConstantMODE_UNIQUE_OPEN, typeint๐MODE_SEQUENTIALโ ConstantMODE_SEQUENTIAL, typeint๐ขMODE_APPENDโ ConstantMODE_APPEND, typeintโSEEK_SETโ ConstantSEEK_SET, typeint๐ฏSEEK_CURโ ConstantSEEK_CUR, typeint๐SEEK_ENDโ ConstantSEEK_END, typeint๐DISPLACEMENT_CURRENTโ ConstantDISPLACEMENT_CURRENT, typeint๐DISP_CURโ ConstantDISP_CUR, typeint๐THREAD_SINGLEโ ConstantTHREAD_SINGLE, typeint๐งต
fr fr, every single one of these is literally just a constant of type int. that's the whole tea. no behaviour notes, no tricks, just vibes and integers ๐
and yeah, THREAD_SINGLE is where we're leaving off โ the energy is still going, don't you worry ๐ฆ
...and the roster just keeps going, bestie. We're still deep in the mpi4py.MPI constant-and-object directory, and it does <em>not</em> stop. Here's the next batch, each one exactly as it appears: ๐
THREAD_FUNNELED(#mpi4py.MPI.THREAD_FUNNELED) โ a constant of typeint, i.e. the classichttps://docs.python.org/3/library/functions.html#intsituation.THREAD_SERIALIZED(#mpi4py.MPI.THREAD_SERIALIZED) โ a constant of typeint(https://docs.python.org/3/library/functions.html#int).THREAD_MULTIPLE(#mpi4py.MPI.THREAD_MULTIPLE) โ a constant of typeint(https://docs.python.org/3/library/functions.html#int). Yes queen, the thread squad is complete. ๐
VERSION(#mpi4py.MPI.VERSION) โ a constant of typeint(https://docs.python.org/3/library/functions.html#int).SUBVERSION(#mpi4py.MPI.SUBVERSION) โ a constant of typeint(https://docs.python.org/3/library/functions.html#int). Her little sister, iconic. ๐
Now the MAX_ family, aka the "how long can this string possibly be" girlies. All of them are constants of type int (https://docs.python.org/3/library/functions.html#int), no cap:
MAX_PROCESSOR_NAME(#mpi4py.MPI.MAX_PROCESSOR_NAME)MAX_ERROR_STRING(#mpi4py.MPI.MAX_ERROR_STRING)MAX_PORT_NAME(#mpi4py.MPI.MAX_PORT_NAME)MAX_INFO_KEY(#mpi4py.MPI.MAX_INFO_KEY)MAX_INFO_VAL(#mpi4py.MPI.MAX_INFO_VAL)MAX_OBJECT_NAME(#mpi4py.MPI.MAX_OBJECT_NAME)MAX_DATAREP_STRING(#mpi4py.MPI.MAX_DATAREP_STRING)MAX_LIBRARY_VERSION_STRING(#mpi4py.MPI.MAX_LIBRARY_VERSION_STRING)MAX_PSET_NAME_LEN(#mpi4py.MPI.MAX_PSET_NAME_LEN)MAX_STRINGTAG_LEN(#mpi4py.MPI.MAX_STRINGTAG_LEN)
Ten of them. All int. All here. We ate. โจ
And now the main character section: the datatype objects. Every single one of these is an object of type Datatype (#mpi4py.MPI.Datatype), and each lives at its own little anchor. Say hi: ๐ธ
DATATYPE_NULL(#mpi4py.MPI.DATATYPE_NULL) โ an object of typeDatatype(#mpi4py.MPI.Datatype).PACKED(#mpi4py.MPI.PACKED) โ an object of typeDatatype(#mpi4py.MPI.Datatype).BYTE(#mpi4py.MPI.BYTE) โ an object of typeDatatype(#mpi4py.MPI.Datatype).AINT(#mpi4py.MPI.AINT) โ an object of typeDatatype(#mpi4py.MPI.Datatype).OFFSET(#mpi4py.MPI.OFFSET) โ an object of typeDatatype(#mpi4py.MPI.Datatype).COUNT(#mpi4py.MPI.COUNT) โ an object of typeDatatype(#mpi4py.MPI.Datatype).CHAR(#mpi4py.MPI.CHAR) โ an object of typeDatatype(#mpi4py.MPI.Datatype).WCHAR(#mpi4py.MPI.WCHAR) โ an object of typeDatatype(#mpi4py.MPI.Datatype).SIGNED_CHAR(#mpi4py.MPI.SIGNED_CHAR) โ an object of typeDatatype(#mpi4py.MPI.Datatype).
Heads up bestie: that's where this part cuts off mid-roll call. The datatype parade is not over. ๐ฆ
SHORTโ ObjectSHORTof typeDatatypeโจINTโ ObjectINTof typeDatatype๐LONGโ ObjectLONGof typeDatatype๐LONG_LONGโ ObjectLONG_LONGof typeDatatype๐ฆUNSIGNED_CHARโ ObjectUNSIGNED_CHARof typeDatatype๐ธUNSIGNED_SHORTโ ObjectUNSIGNED_SHORTof typeDatatype๐UNSIGNEDโ ObjectUNSIGNEDof typeDatatype๐ซถUNSIGNED_LONGโ ObjectUNSIGNED_LONGof typeDatatype๐ญUNSIGNED_LONG_LONGโ ObjectUNSIGNED_LONG_LONGof typeDatatype๐ฅFLOATโ ObjectFLOATof typeDatatype๐DOUBLEโ ObjectDOUBLEof typeDatatype๐LONG_DOUBLEโ ObjectLONG_DOUBLEof typeDatatypeโญC_BOOLโ ObjectC_BOOLof typeDatatype๐INT8_Tโ ObjectINT8_Tof typeDatatype๐INT16_Tโ ObjectINT16_Tof typeDatatype๐INT32_Tโ ObjectINT32_Tof typeDatatype๐งINT64_Tโ ObjectINT64_Tof typeDatatype๐UINT8_Tโ ObjectUINT8_Tof typeDatatypeโจUINT16_Tโ ObjectUINT16_Tof typeDatatype๐UINT32_Tโ ObjectUINT32_Tof typeDatatype๐UINT64_Tโ ObjectUINT64_Tof typeDatatype๐ฆFLOAT16_Tโ ObjectFLOAT16_Tof typeDatatype๐ธFLOAT32_Tโ ObjectFLOAT32_Tof typeDatatype๐FLOAT64_Tโ ObjectFLOAT64_Tof typeDatatype๐ซถBFLOAT16_Tโ ObjectBFLOAT16_Tof typeDatatype๐ญC_COMPLEXโ ObjectC_COMPLEXof typeDatatype๐ฅC_FLOAT_COMPLEXโ ObjectC_FLOAT_COMPLEXof typeDatatype๐
okay bestie we're still in the datatype lineup ๐
same energy as before โ every single one of these is a Datatype object, and imma keep them in the exact order they showed up, no skipping, no reordering, periodt:
C_DOUBLE_COMPLEXโ aDatatypeobject, that's the whole vibe ๐ฆC_LONG_DOUBLE_COMPLEXโ yep, anotherDatatypeobject, she's realCXX_BOOLโDatatypeobject, slayCXX_FLOAT_COMPLEXโ you guessed it, aDatatypeobject โจCXX_DOUBLE_COMPLEXโDatatypeobject, iconic behaviorCXX_LONG_DOUBLE_COMPLEXโ still aDatatypeobject, bestie, they're all like thisSHORT_INTโDatatypeobject ๐INT_INTโDatatypeobject, okurrTWOINTโ aDatatypeobject, not me checking twice ๐LONG_INTโDatatypeobject fr frFLOAT_INTโDatatypeobject, lowkey stunningDOUBLE_INTโDatatypeobject ๐ธLONG_DOUBLE_INTโDatatypeobject, the long one of the groupCHARACTERโDatatypeobject, main character energy obviously ๐LOGICALโDatatypeobject, makes sense to meINTEGERโDatatypeobject ๐REALโDatatypeobject, keeping it realDOUBLE_PRECISIONโDatatypeobject, precise as alwaysCOMPLEXโDatatypeobject, it's giving layers ๐งDOUBLE_COMPLEXโDatatypeobject, twice the complexityLOGICAL1โDatatypeobject โญLOGICAL2โDatatypeobject, the sequelLOGICAL4โDatatypeobject, still goingLOGICAL8โDatatypeobject ๐LOGICAL16โDatatypeobject, big number energyINTEGER1โDatatypeobject ๐ซถINTEGER2โDatatypeobject, and we're still countingโฆ
and yeah the list just keeps going, so hold that thought bestie ๐ญ โ there's more coming right up ๐
okay continuing the datatype roll call, bestie โ same deal as before, every single one of these is an object of type Datatype ๐
INTEGER4โ ObjectINTEGER4of typeDatatypeโจINTEGER8โ ObjectINTEGER8of typeDatatype๐INTEGER16โ ObjectINTEGER16of typeDatatype๐REAL2โ ObjectREAL2of typeDatatype๐ฆREAL4โ ObjectREAL4of typeDatatype๐ธREAL8โ ObjectREAL8of typeDatatype๐ซREAL16โ ObjectREAL16of typeDatatypeโญCOMPLEX4โ ObjectCOMPLEX4of typeDatatype๐COMPLEX8โ ObjectCOMPLEX8of typeDatatype๐งCOMPLEX16โ ObjectCOMPLEX16of typeDatatype๐COMPLEX32โ ObjectCOMPLEX32of typeDatatype๐ฅUNSIGNED_INTโ ObjectUNSIGNED_INTof typeDatatype๐ซถSIGNED_SHORTโ ObjectSIGNED_SHORTof typeDatatype๐SIGNED_INTโ ObjectSIGNED_INTof typeDatatypeโจSIGNED_LONGโ ObjectSIGNED_LONGof typeDatatype๐SIGNED_LONG_LONGโ ObjectSIGNED_LONG_LONGof typeDatatype๐BOOLโ ObjectBOOLof typeDatatype๐SINT8_Tโ ObjectSINT8_Tof typeDatatype๐ทSINT16_Tโ ObjectSINT16_Tof typeDatatype๐ฆSINT32_Tโ ObjectSINT32_Tof typeDatatype๐SINT64_Tโ ObjectSINT64_Tof typeDatatype๐F_BOOLโ ObjectF_BOOLof typeDatatype๐F_INTโ ObjectF_INTof typeDatatype๐ธF_FLOATโ ObjectF_FLOATof typeDatatype๐ฆF_DOUBLEโ ObjectF_DOUBLEof typeDatatype๐F_COMPLEXโ ObjectF_COMPLEXof typeDatatypeโจF_FLOAT_COMPLEXโ ObjectF_FLOAT_COMPLEXof typeDatatype๐ฅF_DOUBLE_COMPLEXโ ObjectF_DOUBLE_COMPLEXof typeDatatype๐
ngl the way this list just keeps going? iconic. and there's more coming, so stay with me ๐ซถ
โฆand the roll call just keeps going, bestie, we are not done yet โจ
REQUEST_NULLโ theREQUEST_NULLobject, typeRequest๐ซถMESSAGE_NULLโ theMESSAGE_NULLobject, typeMessageMESSAGE_NO_PROCโ theMESSAGE_NO_PROCobject, typeMessage
okay now we're in our Op era and it's giving math class but make it fashion ๐
every single one of these is an object of type Op:
OP_NULLโ theOP_NULLobject, typeOpMAXโ theMAXobject, typeOpMINโ theMINobject, typeOpSUMโ theSUMobject, typeOpPRODโ thePRODobject, typeOpLANDโ theLANDobject, typeOpBANDโ theBANDobject, typeOpLORโ theLORobject, typeOpBORโ theBORobject, typeOpLXORโ theLXORobject, typeOpBXORโ theBXORobject, typeOpMAXLOCโ theMAXLOCobject, typeOpMINLOCโ theMINLOCobject, typeOpREPLACEโ theREPLACEobject, typeOpNO_OPโ theNO_OPobject, typeOp
groups, bestie, groups ๐ธ
GROUP_NULLโ theGROUP_NULLobject, typeGroupGROUP_EMPTYโ theGROUP_EMPTYobject, typeGroup
info time, no cap ๐ฆ
INFO_NULLโ theINFO_NULLobject, typeInfoINFO_ENVโ theINFO_ENVobject, typeInfo
error handlers, aka the "who's gonna tell them" squad ๐ญ
ERRHANDLER_NULLโ theERRHANDLER_NULLobject, typeErrhandlerERRORS_RETURNโ theERRORS_RETURNobject, typeErrhandlerERRORS_ABORTโ theERRORS_ABORTobject, typeErrhandlerERRORS_ARE_FATALโ theERRORS_ARE_FATALobject, typeErrhandler
comms, the main character energy of the whole module ๐
SESSION_NULLโ theSESSION_NULLobject, typeSessionCOMM_NULLโ theCOMM_NULLobject, typeCommCOMM_SELFโ theCOMM_SELFobject, typeIntracommCOMM_WORLDโ theCOMM_WORLDobject, typeIntracomm
and one last one for the window girlies ๐ช
WIN_NULLโ theWIN_NULLobject, typeWin
every name up there is literally spelled exactly like that, all caps, underscores and all โ do not freestyle it, bestie, COMM_WORLD is not COMMWORLD and she will not forgive you ๐
okay bestie, last five rows of that table, hold on to your wig ๐
FILE_NULLโ objectFILE_NULL, and its type isFileBOTTOMโ objectBOTTOM, typeBottomTypeIN_PLACEโ objectIN_PLACE, typeInPlaceTypeBUFFER_AUTOMATICโ objectBUFFER_AUTOMATIC, typeBufferAutomaticTypepickleโ objectpickle, typePickle
โจ and nowโฆ the CONSTANTS โจ
no cap, this is just a big ol' parade of int values. every single one of them is a plain Python int (you know, the int from the Python standard library docs), and every one is literally equal to its own name. iconic behaviour honestly ๐
mpi4py.MPI.UNDEFINEDโmpi4py.MPI.UNDEFINED: int = UNDEFINED. ConstantUNDEFINED, typeint๐mpi4py.MPI.ANY_SOURCEโmpi4py.MPI.ANY_SOURCE: int = ANY_SOURCE. ConstantANY_SOURCE, typeintmpi4py.MPI.ANY_TAGโmpi4py.MPI.ANY_TAG: int = ANY_TAG. ConstantANY_TAG, typeintmpi4py.MPI.PROC_NULLโmpi4py.MPI.PROC_NULL: int = PROC_NULL. ConstantPROC_NULL, typeintmpi4py.MPI.ROOTโmpi4py.MPI.ROOT: int = ROOT. ConstantROOT, typeintmpi4py.MPI.KEYVAL_INVALIDโmpi4py.MPI.KEYVAL_INVALID: int = KEYVAL_INVALID. ConstantKEYVAL_INVALID, typeintmpi4py.MPI.TAG_UBโmpi4py.MPI.TAG_UB: int = TAG_UB. ConstantTAG_UB, typeintmpi4py.MPI.IOโmpi4py.MPI.IO: int = IO. ConstantIO, typeintmpi4py.MPI.WTIME_IS_GLOBALโmpi4py.MPI.WTIME_IS_GLOBAL: int = WTIME_IS_GLOBAL. ConstantWTIME_IS_GLOBAL, typeintmpi4py.MPI.UNIVERSE_SIZEโmpi4py.MPI.UNIVERSE_SIZE: int = UNIVERSE_SIZE. ConstantUNIVERSE_SIZE, typeintmpi4py.MPI.APPNUMโmpi4py.MPI.APPNUM: int = APPNUM. ConstantAPPNUM, typeintmpi4py.MPI.LASTUSEDCODEโmpi4py.MPI.LASTUSEDCODE: int = LASTUSEDCODE. ConstantLASTUSEDCODE, typeintmpi4py.MPI.WIN_BASEโmpi4py.MPI.WIN_BASE: int = WIN_BASE. ConstantWIN_BASE, typeintmpi4py.MPI.WIN_SIZEโmpi4py.MPI.WIN_SIZE: int = WIN_SIZE. ConstantWIN_SIZE, typeintmpi4py.MPI.WIN_DISP_UNITโmpi4py.MPI.WIN_DISP_UNIT: int = WIN_DISP_UNIT. ConstantWIN_DISP_UNIT, typeintmpi4py.MPI.WIN_CREATE_FLAVORโmpi4py.MPI.WIN_CREATE_FLAVOR: int = WIN_CREATE_FLAVOR. ConstantWIN_CREATE_FLAVOR, typeintmpi4py.MPI.WIN_FLAVORโmpi4py.MPI.WIN_FLAVOR: int = WIN_FLAVOR. ConstantWIN_FLAVOR, typeintmpi4py.MPI.WIN_MODELโmpi4py.MPI.WIN_MODEL: int = WIN_MODEL. ConstantWIN_MODEL, typeintmpi4py.MPI.SUCCESSโmpi4py.MPI.SUCCESS: int = SUCCESS. ConstantSUCCESS, typeintmpi4py.MPI.ERR_LASTCODEโmpi4py.MPI.ERR_LASTCODE: int = ERR_LASTCODE. ConstantERR_LASTCODE, typeintmpi4py.MPI.ERR_ABIโmpi4py.MPI.ERR_ABI: int = ERR_ABI. ConstantERR_ABI, typeintmpi4py.MPI.ERR_TYPEโmpi4py.MPI.ERR_TYPE: int = ERR_TYPE. ConstantERR_TYPE, typeintmpi4py.MPI.ERR_REQUESTโmpi4py.MPI.ERR_REQUEST: int = ERR_REQUEST. ConstantERR_REQUEST, typeintmpi4py.MPI.ERR_OPโmpi4py.MPI.ERR_OP: int = ERR_OP. ConstantERR_OP, typeintmpi4py.MPI.ERR_GROUPโmpi4py.MPI.ERR_GROUP: int = ERR_GROUP. ConstantERR_GROUP, typeintmpi4py.MPI.ERR_INFOโmpi4py.MPI.ERR_INFO: int = ERR_INFO. ConstantERR_INFO, typeintmpi4py.MPI.ERR_ERRHANDLERโmpi4py.MPI.ERR_ERRHANDLER: int = ERR_ERRHANDLER. ConstantERR_ERRHANDLER, typeintmpi4py.MPI.ERR_SESSIONโmpi4py.MPI.ERR_SESSION: int = ERR_SESSION. ConstantERR_SESSION, typeintmpi4py.MPI.ERR_COMMโmpi4py.MPI.ERR_COMM: int = ERR_COMM. ConstantERR_COMM, typeintmpi4py.MPI.ERR_WINโmpi4py.MPI.ERR_WIN: int = ERR_WIN. ConstantERR_WIN, typeintmpi4py.MPI.ERR_FILEโmpi4py.MPI.ERR_FILE: int = ERR_FILE. ConstantERR_FILE, typeintmpi4py.MPI.ERR_BUFFERโmpi4py.MPI.ERR_BUFFER: int = ERR_BUFFER. ConstantERR_BUFFER, typeintmpi4py.MPI.ERR_COUNTโmpi4py.MPI.ERR_COUNT: int = ERR_COUNT. ConstantERR_COUNT, typeintmpi4py.MPI.ERR_TAGโmpi4py.MPI.ERR_TAG: int = ERR_TAG. ConstantERR_TAG, typeintmpi4py.MPI.ERR_RANKโmpi4py.MPI.ERR_RANK: int = ERR_RANK. ConstantERR_RANK, typeintmpi4py.MPI.ERR_ROOTโmpi4py.MPI.ERR_ROOT: int = ERR_ROOT. ConstantERR_ROOT, typeintmpi4py.MPI.ERR_TRUNCATEโmpi4py.MPI.ERR_TRUNCATE: int = ERR_TRUNCATE. ConstantERR_TRUNCATE, typeintmpi4py.MPI.ERR_IN_STATUSโmpi4py.MPI.ERR_IN_STATUS: int = ERR_IN_STATUS. ConstantERR_IN_STATUS, typeint
that's the whole error-code squad right there, every last one, bestie ๐
okay bestie, we're deep in the error constant zone now ๐ธ โ every single one of these is a constant of type int (the regular Python int, the one that lives at https://docs.python.org/3/library/functions.html#int), and each one's value is literally its own name. No cap. Here we go, one by one, no skipping, we're finishing this list together ๐
mpi4py.MPI.ERR_PENDING
mpi4py.MPI.ERR_PENDING: int = ERR_PENDING
Constant ERR_PENDING of type int. The name is doing the absolute most and I respect it โจ
mpi4py.MPI.ERR_TOPOLOGY
mpi4py.MPI.ERR_TOPOLOGY: int = ERR_TOPOLOGY
Constant ERR_TOPOLOGY of type int. Say it with me: topology ๐ซ
mpi4py.MPI.ERR_DIMS
mpi4py.MPI.ERR_DIMS: int = ERR_DIMS
Constant ERR_DIMS of type int. Short name, big energy ๐
mpi4py.MPI.ERR_ARG
mpi4py.MPI.ERR_ARG: int = ERR_ARG
Constant ERR_ARG of type int. Three letters. Iconic minimalism ๐ฆ
mpi4py.MPI.ERR_OTHER
mpi4py.MPI.ERR_OTHER: int = ERR_OTHER
Constant ERR_OTHER of type int. The "miscellaneous" of error constants and honestly? Relatable ๐ซถ
mpi4py.MPI.ERR_UNKNOWN
mpi4py.MPI.ERR_UNKNOWN: int = ERR_UNKNOWN
Constant ERR_UNKNOWN of type int. Mysterious. Enigmatic. Main character ๐ฅ
mpi4py.MPI.ERR_INTERN
mpi4py.MPI.ERR_INTERN: int = ERR_INTERN
Constant ERR_INTERN of type int. Internal business only, we don't ask questions ๐
mpi4py.MPI.ERR_KEYVAL
mpi4py.MPI.ERR_KEYVAL: int = ERR_KEYVAL
Constant ERR_KEYVAL of type int. Key-value coded, literally ๐
mpi4py.MPI.ERR_NO_MEM
mpi4py.MPI.ERR_NO_MEM: int = ERR_NO_MEM
Constant ERR_NO_MEM of type int. Deep breaths, bestie ๐ญ
mpi4py.MPI.ERR_INFO_KEY
mpi4py.MPI.ERR_INFO_KEY: int = ERR_INFO_KEY
Constant ERR_INFO_KEY of type int. The key half of the info duo ๐
mpi4py.MPI.ERR_INFO_VALUE
mpi4py.MPI.ERR_INFO_VALUE: int = ERR_INFO_VALUE
Constant ERR_INFO_VALUE of type int. And here's the value half, they come as a set ๐
mpi4py.MPI.ERR_INFO_NOKEY
mpi4py.MPI.ERR_INFO_NOKEY: int = ERR_INFO_NOKEY
Constant ERR_INFO_NOKEY of type int. No key, no problem, we still list it ๐
mpi4py.MPI.ERR_SPAWN
mpi4py.MPI.ERR_SPAWN: int = ERR_SPAWN
Constant ERR_SPAWN of type int. Spawn like a video game, obsessed ๐ฎ
mpi4py.MPI.ERR_PORT
mpi4py.MPI.ERR_PORT: int = ERR_PORT
Constant ERR_PORT of type int. Four letters, maximum vibe ๐
mpi4py.MPI.ERR_SERVICE
mpi4py.MPI.ERR_SERVICE: int = ERR_SERVICE
Constant ERR_SERVICE of type int. Customer service voice: activated ๐
mpi4py.MPI.ERR_NAME
mpi4py.MPI.ERR_NAME: int = ERR_NAME
Constant ERR_NAME of type int. What's in a name? This constant, apparently โจ
mpi4py.MPI.ERR_PROC_ABORTED
mpi4py.MPI.ERR_PROC_ABORTED: int = ERR_PROC_ABORTED
Constant ERR_PROC_ABORTED of type int. Long name, full drama, love that for it ๐ญ
mpi4py.MPI.ERR_BASE
mpi4py.MPI.ERR_BASE: int = ERR_BASE
Constant ERR_BASE of type int. The foundation, the blueprint, the base ๐
mpi4py.MPI.ERR_SIZE
mpi4py.MPI.ERR_SIZE: int = ERR_SIZE
Constant ERR_SIZE of type int. Size matters, and so does listing every constant ๐
mpi4py.MPI.ERR_DISP
mpi4py.MPI.ERR_DISP: int = ERR_DISP
Constant ERR_DISP of type int. Short for displacement and short in general ๐ฆ
mpi4py.MPI.ERR_ASSERT
mpi4py.MPI.ERR_ASSERT: int = ERR_ASSERT
Constant ERR_ASSERT of type int. Asserting itself, as it should ๐
mpi4py.MPI.ERR_LOCKTYPE
mpi4py.MPI.ERR_LOCKTYPE: int = ERR_LOCKTYPE
Constant ERR_LOCKTYPE of type int. Locked in ๐
mpi4py.MPI.ERR_RMA_CONFLICT
mpi4py.MPI.ERR_RMA_CONFLICT: int = ERR_RMA_CONFLICT
Constant ERR_RMA_CONFLICT of type int. The RMA era begins and the names get longer, we love a glow-up ๐
mpi4py.MPI.ERR_RMA_SYNC
mpi4py.MPI.ERR_RMA_SYNC: int = ERR_RMA_SYNC
Constant ERR_RMA_SYNC of type int. Syncing up with the group chat ๐ฌ
mpi4py.MPI.ERR_RMA_RANGE
mpi4py.MPI.ERR_RMA_RANGE: int = ERR_RMA_RANGE
Constant ERR_RMA_RANGE of type int. Out of range but never out of style ๐
mpi4py.MPI.ERR_RMA_ATTACH
mpi4py.MPI.ERR_RMA_ATTACH: int = ERR_RMA_ATTACH
Constant ERR_RMA_ATTACH of type int. Attachment issues, but make it MPI ๐ญ
mpi4py.MPI.ERR_RMA_SHARED
mpi4py.MPI.ERR_RMA_SHARED: int = ERR_RMA_SHARED
Constant ERR_RMA_SHARED of type int. Sharing is caring, bestie ๐ซถ
mpi4py.MPI.ERR_RMA_FLAVOR
mpi4py.MPI.ERR_RMA_FLAVOR: int = ERR_RMA_FLAVOR
Constant ERR_RMA_FLAVOR of type int. Flavor?! In MY error constant list?! Yes, and it ate ๐
mpi4py.MPI.ERR_BAD_FILE
mpi4py.MPI.ERR_BAD_FILE: int = ERR_BAD_FILE
Constant ERR_BAD_FILE of type int. Bad file, bad file, whatcha gonna do ๐
mpi4py.MPI.ERR_NO_SUCH_FILE
mpi4py.MPI.ERR_NO_SUCH_FILE: int = ERR_NO_SUCH_FILE
Constant ERR_NO_SUCH_FILE of type int. It's not there. It was never there. ๐
mpi4py.MPI.ERR_FILE_EXISTS
mpi4py.MPI.ERR_FILE_EXISTS: int = ERR_FILE_EXISTS
Constant ERR_FILE_EXISTS of type int. It IS there, actually, and it was there first ๐
mpi4py.MPI.ERR_FILE_IN_USE
mpi4py.MPI.ERR_FILE_IN_USE: int = ERR_FILE_IN_USE
Constant ERR_FILE_IN_USE of type int. Currently busy, do not perceive it ๐
mpi4py.MPI.ERR_AMODE
mpi4py.MPI.ERR_AMODE: int = ERR_AMODE
Constant ERR_AMODE of type int. Access mode, abbreviated, efficient, slay โจ
mpi4py.MPI.ERR_ACCESS
mpi4py.MPI.ERR_ACCESS: int = ERR_ACCESS
Constant ERR_ACCESS of type int. Access denied, respectfully ๐ซ
mpi4py.MPI.ERR_READ_ONLY
mpi4py.MPI.ERR_READ_ONLY: int = ERR_READ_ONLY
Constant ERR_READ_ONLY of type int. Look but don't touch, fr fr ๐
mpi4py.MPI.ERR_NO_SPACE
mpi4py.MPI.ERR_NO_SPACE: int = ERR_NO_SPACE
Constant ERR_NO_SPACE of type int. No room at the inn ๐ญ
mpi4py.MPI.ERR_QUOTA
mpi4py.MPI.ERR_QUOTA: int = ERR_QUOTA
Constant ERR_QUOTA of type int. You've hit your limit bestie, go touch grass ๐ธ
mpi4py.MPI.ERR_NOT_SAME
mpi4py.MPI.ERR_NOT_SAME: int = ERR_NOT_SAME
Constant ERR_NOT_SAME of type int. Not the same, and it's not even trying to be ๐ฆ
mpi4py.MPI.ERR_IO
mpi4py.MPI.ERR_IO: int = ERR_IO
Constant ERR_IO of type int. Two letters, maximum chaos potential ๐ฅ
mpi4py.MPI.ERR_UNSUPPORTED_OPERATION
mpi4py.MPI.ERR_UNSUPPORTED_OPERATION: int = ERR_UNSUPPORTED_OPERATION
Constant ERR_UNSUPPORTED_OPERATION of type int. We do not support that operation and we said what we said ๐
mpi4py.MPI.ERR_UNSUPPORTED_DATAREP
mpi4py.MPI.ERR_UNSUPPORTED_DATAREP: int = ERR_UNSUPPORTED_DATAREP
Constant ERR_UNSUPPORTED_DATAREP of type int. Same energy, different data representation, no cap ๐
mpi4py.MPI.ERR_CONVERSION
mpi4py.MPI.ERR_CONVERSION: int = ERR_CONVERSION
Constant ERR_CONVERSION of type int. Glow-up attempt failed to convert ๐ญ
mpi4py.MPI.ERR_DUP_DATAREP
mpi4py.MPI.ERR_DUP_DATAREP: int = ERR_DUP_DATAREP
Constant ERR_DUP_DATAREP of type int. Duplicate datarep, we've seen this one before ๐ซ
mpi4py.MPI.ERR_VALUE_TOO_LARGE
mpi4py.MPI.ERR_VALUE_TOO_LARGE: int = ERR_VALUE_TOO_LARGE
Constant ERR_VALUE_TOO_LARGE of type int. Too much. Too big. Too powerful. ๐
mpi4py.MPI.ERR_REVOKED
mpi4py.MPI.ERR_REVOKED: int = ERR_REVOKED
Constant ERR_REVOKED of type int. Revoked, like your group chat privileges ๐
mpi4py.MPI.ERR_PROC_FAILED
mpi4py.MPI.ERR_PROC_FAILED: int = ERR_PROC_FAILED
Constant ERR_PROC_FAILED of type int. And we close out this batch with the saddest name of the bunch, rest in pieces ๐ญ๐ซถ
๐ฉท mpi4py.MPI.ERR_PROC_FAILED_PENDING
mpi4py.MPI.ERR_PROC_FAILED_PENDING: int = ERR_PROC_FAILED_PENDING
Constant ERR_PROC_FAILED_PENDING, and she's of type int. that's the whole entry bestie, no crumbs left behind ๐
๐งก mpi4py.MPI.ORDER_C
mpi4py.MPI.ORDER_C: int = ORDER_C
Constant ORDER_C of type int. the C is right there in the name, slay ๐
๐งก mpi4py.MPI.ORDER_FORTRAN
mpi4py.MPI.ORDER_FORTRAN: int = ORDER_FORTRAN
Constant ORDER_FORTRAN of type int. her full legal name, no nicknames ๐ธ
๐งก mpi4py.MPI.ORDER_F
mpi4py.MPI.ORDER_F: int = ORDER_F
Constant ORDER_F of type int. the short version of the above, because she contains multitudes โจ
๐ mpi4py.MPI.TYPECLASS_LOGICAL
mpi4py.MPI.TYPECLASS_LOGICAL: int = TYPECLASS_LOGICAL
Constant TYPECLASS_LOGICAL of type int. typeclass girlies rise ๐ซถ
๐ mpi4py.MPI.TYPECLASS_INTEGER
mpi4py.MPI.TYPECLASS_INTEGER: int = TYPECLASS_INTEGER
Constant TYPECLASS_INTEGER of type int. and yes she is herself an int, we love a self-consistent queen ๐
๐ mpi4py.MPI.TYPECLASS_REAL
mpi4py.MPI.TYPECLASS_REAL: int = TYPECLASS_REAL
Constant TYPECLASS_REAL of type int. keeping it real, literally โจ
๐ mpi4py.MPI.TYPECLASS_COMPLEX
mpi4py.MPI.TYPECLASS_COMPLEX: int = TYPECLASS_COMPLEX
Constant TYPECLASS_COMPLEX of type int. she's complicated and that's her brand ๐
๐ฆ mpi4py.MPI.DISTRIBUTE_NONE
mpi4py.MPI.DISTRIBUTE_NONE: int = DISTRIBUTE_NONE
Constant DISTRIBUTE_NONE of type int. distributing absolutely nothing, and doing it flawlessly ๐
๐ฆ mpi4py.MPI.DISTRIBUTE_BLOCK
mpi4py.MPI.DISTRIBUTE_BLOCK: int = DISTRIBUTE_BLOCK
Constant DISTRIBUTE_BLOCK of type int. block party, everyone invited ๐
๐ฆ mpi4py.MPI.DISTRIBUTE_CYCLIC
mpi4py.MPI.DISTRIBUTE_CYCLIC: int = DISTRIBUTE_CYCLIC
Constant DISTRIBUTE_CYCLIC of type int. going in circles but make it fashion ๐
๐ฆ mpi4py.MPI.DISTRIBUTE_DFLT_DARG
mpi4py.MPI.DISTRIBUTE_DFLT_DARG: int = DISTRIBUTE_DFLT_DARG
Constant DISTRIBUTE_DFLT_DARG of type int. the default one, the darg of it all, no cap ๐
๐ mpi4py.MPI.COMBINER_NAMED
mpi4py.MPI.COMBINER_NAMED: int = COMBINER_NAMED
Constant COMBINER_NAMED of type int. welcome to the COMBINER cinematic universe, we're here all day โจ
๐ mpi4py.MPI.COMBINER_DUP
mpi4py.MPI.COMBINER_DUP: int = COMBINER_DUP
Constant COMBINER_DUP of type int. duplicating the vibe fr fr ๐
๐ mpi4py.MPI.COMBINER_CONTIGUOUS
mpi4py.MPI.COMBINER_CONTIGUOUS: int = COMBINER_CONTIGUOUS
Constant COMBINER_CONTIGUOUS of type int. all in a row, no gaps, iconic behavior ๐
๐ mpi4py.MPI.COMBINER_VECTOR
mpi4py.MPI.COMBINER_VECTOR: int = COMBINER_VECTOR
Constant COMBINER_VECTOR of type int. she has direction and she has magnitude, periodt ๐
๐ mpi4py.MPI.COMBINER_HVECTOR
mpi4py.MPI.COMBINER_HVECTOR: int = COMBINER_HVECTOR
Constant COMBINER_HVECTOR of type int. the H stands for her, obviously ๐
๐ mpi4py.MPI.COMBINER_INDEXED
mpi4py.MPI.COMBINER_INDEXED: int = COMBINER_INDEXED
Constant COMBINER_INDEXED of type int. indexed and unbothered ๐ซถ
๐ mpi4py.MPI.COMBINER_HINDEXED
mpi4py.MPI.COMBINER_HINDEXED: int = COMBINER_HINDEXED
Constant COMBINER_HINDEXED of type int. the H returns, she's booked and busy ๐
๐ mpi4py.MPI.COMBINER_INDEXED_BLOCK
mpi4py.MPI.COMBINER_INDEXED_BLOCK: int = COMBINER_INDEXED_BLOCK
Constant COMBINER_INDEXED_BLOCK of type int. indexed AND blocked, a crossover event ๐ฅ
๐ mpi4py.MPI.COMBINER_HINDEXED_BLOCK
mpi4py.MPI.COMBINER_HINDEXED_BLOCK: int = COMBINER_HINDEXED_BLOCK
Constant COMBINER_HINDEXED_BLOCK of type int. the sequel to the crossover, and honestly it ate ๐ญ
๐ mpi4py.MPI.COMBINER_STRUCT
mpi4py.MPI.COMBINER_STRUCT: int = COMBINER_STRUCT
Constant COMBINER_STRUCT of type int. structured, organized, thriving ๐ธ
๐ mpi4py.MPI.COMBINER_SUBARRAY
mpi4py.MPI.COMBINER_SUBARRAY: int = COMBINER_SUBARRAY
Constant COMBINER_SUBARRAY of type int. a whole array but like, a sub one ๐
๐ mpi4py.MPI.COMBINER_DARRAY
mpi4py.MPI.COMBINER_DARRAY: int = COMBINER_DARRAY
Constant COMBINER_DARRAY of type int. the D is doing a lot of heavy lifting here and we respect it ๐
๐ mpi4py.MPI.COMBINER_RESIZED
mpi4py.MPI.COMBINER_RESIZED: int = COMBINER_RESIZED
Constant COMBINER_RESIZED of type int. glow-up arc, resized and reborn โจ
๐ mpi4py.MPI.COMBINER_VALUE_INDEX
mpi4py.MPI.COMBINER_VALUE_INDEX: int = COMBINER_VALUE_INDEX
Constant COMBINER_VALUE_INDEX of type int. values AND index, she's doing both jobs ๐
๐ mpi4py.MPI.COMBINER_F90_INTEGER
mpi4py.MPI.COMBINER_F90_INTEGER: int = COMBINER_F90_INTEGER
Constant COMBINER_F90_INTEGER of type int. Fortran 90 said hello and we said hi back ๐ซถ
๐ mpi4py.MPI.COMBINER_F90_REAL
mpi4py.MPI.COMBINER_F90_REAL: int = COMBINER_F90_REAL
Constant COMBINER_F90_REAL of type int. still Fortran 90, still real ๐
๐ mpi4py.MPI.COMBINER_F90_COMPLEX
mpi4py.MPI.COMBINER_F90_COMPLEX: int = COMBINER_F90_COMPLEX
Constant COMBINER_F90_COMPLEX of type int. the last of the F90 trio, and she understood the assignment ๐
๐ mpi4py.MPI.F_SOURCE
mpi4py.MPI.F_SOURCE: int = F_SOURCE
Constant F_SOURCE of type int. we're in the F_ era now, buckle up bestie ๐
๐ mpi4py.MPI.F_TAG
mpi4py.MPI.F_TAG: int = F_TAG
Constant F_TAG of type int. she's tagged, she's iconic, she's an int ๐
๐ mpi4py.MPI.F_ERROR
mpi4py.MPI.F_ERROR: int = F_ERROR
Constant F_ERROR of type int. error by name, not by nature ๐
๐ mpi4py.MPI.F_STATUS_SIZE
mpi4py.MPI.F_STATUS_SIZE: int = F_STATUS_SIZE
Constant F_STATUS_SIZE of type int. size queen behavior but for statuses ๐ซถ
๐ฅ mpi4py.MPI.IDENT
mpi4py.MPI.IDENT: int = IDENT
Constant IDENT of type int. identical to nothing, she's one of a kind โจ
๐ฅ mpi4py.MPI.CONGRUENT
mpi4py.MPI.CONGRUENT: int = CONGRUENT
Constant CONGRUENT of type int. she matches the energy, she's congruent with it ๐
๐ฅ mpi4py.MPI.SIMILAR
mpi4py.MPI.SIMILAR: int = SIMILAR
Constant SIMILAR of type int. not identical but like, the same vibe ๐ธ
๐ฅ mpi4py.MPI.UNEQUAL
mpi4py.MPI.UNEQUAL: int = UNEQUAL
Constant UNEQUAL of type int. she said we are NOT the same and honestly? valid ๐ญ
๐บ๏ธ mpi4py.MPI.CART
mpi4py.MPI.CART: int = CART
Constant CART of type int. topology arc begins, we're going cartesian ๐งญ
๐บ๏ธ mpi4py.MPI.GRAPH
mpi4py.MPI.GRAPH: int = GRAPH
Constant GRAPH of type int. graph girlies, your moment has arrived ๐
๐บ๏ธ mpi4py.MPI.DIST_GRAPH
mpi4py.MPI.DIST_GRAPH: int = DIST_GRAPH
Constant DIST_GRAPH of type int. the distributed sequel, and she devoured ๐
๐บ๏ธ mpi4py.MPI.UNWEIGHTED
mpi4py.MPI.UNWEIGHTED: int = UNWEIGHTED
Constant UNWEIGHTED of type int. no weights, no baggage, she travels light ๐ฆ
๐บ๏ธ mpi4py.MPI.WEIGHTS_EMPTY
mpi4py.MPI.WEIGHTS_EMPTY: int = WEIGHTS_EMPTY
Constant WEIGHTS_EMPTY of type int. the weights are empty bestie, the container is empty, that's the whole thing ๐ซ
๐ mpi4py.MPI.COMM_TYPE_SHARED
mpi4py.MPI.COMM_TYPE_SHARED: int = COMM_TYPE_SHARED
Constant COMM_TYPE_SHARED of type int. sharing is caring, and she cares ๐ธ
๐ mpi4py.MPI.COMM_TYPE_HW_GUIDED
mpi4py.MPI.COMM_TYPE_HW_GUIDED: int = COMM_TYPE_HW_GUIDED
Constant COMM_TYPE_HW_GUIDED of type int. hardware-guided, main character energy, and that's the last one in this batch so let's keep scrolling ๐๐
๐
mpi4py.MPI.COMM_TYPE_HW_UNGUIDED
mpi4py.MPI.COMM_TYPE_HW_UNGUIDED: int = COMM_TYPE_HW_UNGUIDED
okay so this is the constant COMM_TYPE_HW_UNGUIDED, and its whole deal is that it's an int <https://docs.python.org/3/library/functions.html#int>. that's it, that's the vibe. โจ
๐
mpi4py.MPI.COMM_TYPE_RESOURCE_GUIDED
mpi4py.MPI.COMM_TYPE_RESOURCE_GUIDED: int = COMM_TYPE_RESOURCE_GUIDED
constant COMM_TYPE_RESOURCE_GUIDED, type int <https://docs.python.org/3/library/functions.html#int>. she's giving resource-guided energy and she's an integer, periodt. ๐
๐ซถ mpi4py.MPI.BSEND_OVERHEAD
mpi4py.MPI.BSEND_OVERHEAD: int = BSEND_OVERHEAD
the constant BSEND_OVERHEAD, and bestie, it is of type int <https://docs.python.org/3/library/functions.html#int>. lowkey iconic. ๐
๐ฆ mpi4py.MPI.WIN_FLAVOR_CREATE
mpi4py.MPI.WIN_FLAVOR_CREATE: int = WIN_FLAVOR_CREATE
constant WIN_FLAVOR_CREATE โ an int <https://docs.python.org/3/library/functions.html#int>. window flavor number one, and she is an integer fr fr. โจ
๐ฆ mpi4py.MPI.WIN_FLAVOR_ALLOCATE
mpi4py.MPI.WIN_FLAVOR_ALLOCATE: int = WIN_FLAVOR_ALLOCATE
constant WIN_FLAVOR_ALLOCATE, type int <https://docs.python.org/3/library/functions.html#int>. allocate-flavored, int-shaped, obsessed. ๐
๐ฆ mpi4py.MPI.WIN_FLAVOR_DYNAMIC
mpi4py.MPI.WIN_FLAVOR_DYNAMIC: int = WIN_FLAVOR_DYNAMIC
constant WIN_FLAVOR_DYNAMIC, of type int <https://docs.python.org/3/library/functions.html#int>. dynamic queen, still an int, no cap. ๐
๐ฆ mpi4py.MPI.WIN_FLAVOR_SHARED
mpi4py.MPI.WIN_FLAVOR_SHARED: int = WIN_FLAVOR_SHARED
constant WIN_FLAVOR_SHARED โ int <https://docs.python.org/3/library/functions.html#int>. sharing is caring and it's an integer. ๐ซถ
๐ธ mpi4py.MPI.WIN_SEPARATE
mpi4py.MPI.WIN_SEPARATE: int = WIN_SEPARATE
constant WIN_SEPARATE, type int <https://docs.python.org/3/library/functions.html#int>. separate but still an int, she's doing her own thing. ๐
๐ธ mpi4py.MPI.WIN_UNIFIED
mpi4py.MPI.WIN_UNIFIED: int = WIN_UNIFIED
constant WIN_UNIFIED, of type int <https://docs.python.org/3/library/functions.html#int>. unified and unbothered, and yes, an integer. ๐
โญ mpi4py.MPI.MODE_NOCHECK
mpi4py.MPI.MODE_NOCHECK: int = MODE_NOCHECK
constant MODE_NOCHECK, and she's an int <https://docs.python.org/3/library/functions.html#int>. no check, no stress, all int. โจ
โญ mpi4py.MPI.MODE_NOSTORE
mpi4py.MPI.MODE_NOSTORE: int = MODE_NOSTORE
constant MODE_NOSTORE โ type int <https://docs.python.org/3/library/functions.html#int>. nothing stored except the fact that she's an integer. ๐
โญ mpi4py.MPI.MODE_NOPUT
mpi4py.MPI.MODE_NOPUT: int = MODE_NOPUT
constant MODE_NOPUT, of type int <https://docs.python.org/3/library/functions.html#int>. no putting, but definitely an int. ๐
โญ mpi4py.MPI.MODE_NOPRECEDE
mpi4py.MPI.MODE_NOPRECEDE: int = MODE_NOPRECEDE
constant MODE_NOPRECEDE, type int <https://docs.python.org/3/library/functions.html#int>. nothing precedes her except being an integer. ๐ฆ
โญ mpi4py.MPI.MODE_NOSUCCEED
mpi4py.MPI.MODE_NOSUCCEED: int = MODE_NOSUCCEED
constant MODE_NOSUCCEED โ int <https://docs.python.org/3/library/functions.html#int>. nothing succeeds her exceptโฆ more integers. ๐
๐ฅ mpi4py.MPI.LOCK_EXCLUSIVE
mpi4py.MPI.LOCK_EXCLUSIVE: int = LOCK_EXCLUSIVE
constant LOCK_EXCLUSIVE, of type int <https://docs.python.org/3/library/functions.html#int>. exclusive lock energy, main character, still an int. ๐
๐ฅ mpi4py.MPI.LOCK_SHARED
mpi4py.MPI.LOCK_SHARED: int = LOCK_SHARED
constant LOCK_SHARED, type int <https://docs.python.org/3/library/functions.html#int>. shared lock, shared vibes, shared int-ness. ๐ซถ
๐ mpi4py.MPI.MODE_RDONLY
mpi4py.MPI.MODE_RDONLY: int = MODE_RDONLY
constant MODE_RDONLY, and it's an int <https://docs.python.org/3/library/functions.html#int>. read-only mode, but read this: she's an integer. โจ
๐ mpi4py.MPI.MODE_WRONLY
mpi4py.MPI.MODE_WRONLY: int = MODE_WRONLY
constant MODE_WRONLY โ type int <https://docs.python.org/3/library/functions.html#int>. write-only, but I'm writing this down: int. ๐
๐ mpi4py.MPI.MODE_RDWR
mpi4py.MPI.MODE_RDWR: int = MODE_RDWR
constant MODE_RDWR, of type int <https://docs.python.org/3/library/functions.html#int>. read AND write, she does both, and she's an integer. ๐
๐ธ mpi4py.MPI.MODE_CREATE
mpi4py.MPI.MODE_CREATE: int = MODE_CREATE
constant MODE_CREATE, type int <https://docs.python.org/3/library/functions.html#int>. creating a whole vibe, and also an int. ๐
๐ธ mpi4py.MPI.MODE_EXCL
mpi4py.MPI.MODE_EXCL: int = MODE_EXCL
constant MODE_EXCL โ int <https://docs.python.org/3/library/functions.html#int>. exclusive behavior, inclusive heart, integer soul. ๐ฆ
๐ธ mpi4py.MPI.MODE_DELETE_ON_CLOSE
mpi4py.MPI.MODE_DELETE_ON_CLOSE: int = MODE_DELETE_ON_CLOSE
constant MODE_DELETE_ON_CLOSE, of type int <https://docs.python.org/3/library/functions.html#int>. delete on close bestie, and yes she's an int. ๐
๐ธ mpi4py.MPI.MODE_UNIQUE_OPEN
mpi4py.MPI.MODE_UNIQUE_OPEN: int = MODE_UNIQUE_OPEN
constant MODE_UNIQUE_OPEN, type int <https://docs.python.org/3/library/functions.html#int>. unique open, unique int, we love to see it. ๐
๐ธ mpi4py.MPI.MODE_SEQUENTIAL
mpi4py.MPI.MODE_SEQUENTIAL: int = MODE_SEQUENTIAL
constant MODE_SEQUENTIAL, and she is an int <https://docs.python.org/3/library/functions.html#int>. one thing after another, sequentially, as an integer. โญ
๐ธ mpi4py.MPI.MODE_APPEND
mpi4py.MPI.MODE_APPEND: int = MODE_APPEND
constant MODE_APPEND โ type int <https://docs.python.org/3/library/functions.html#int>. append energy, integer reality. ๐ฅ
๐ง mpi4py.MPI.SEEK_SET
mpi4py.MPI.SEEK_SET: int = SEEK_SET
constant SEEK_SET, of type int <https://docs.python.org/3/library/functions.html#int>. set your position, set your standards, stay an int. ๐
๐ง mpi4py.MPI.SEEK_CUR
mpi4py.MPI.SEEK_CUR: int = SEEK_CUR
constant SEEK_CUR, type int <https://docs.python.org/3/library/functions.html#int>. current position, current mood, current int. ๐
๐ง mpi4py.MPI.SEEK_END
mpi4py.MPI.SEEK_END: int = SEEK_END
constant SEEK_END โ int <https://docs.python.org/3/library/functions.html#int>. seek to the end, but never the end of the int pipeline. ๐
๐ mpi4py.MPI.DISPLACEMENT_CURRENT
mpi4py.MPI.DISPLACEMENT_CURRENT: int = DISPLACEMENT_CURRENT
constant DISPLACEMENT_CURRENT, and bestie, she's an int <https://docs.python.org/3/library/functions.html#int>. displaced? never. an int? always. โจ
๐ mpi4py.MPI.DISP_CUR
mpi4py.MPI.DISP_CUR: int = DISP_CUR
constant DISP_CUR, of type int <https://docs.python.org/3/library/functions.html#int>. the short-king version of the name above, equally an int. ๐
๐ mpi4py.MPI.THREAD_SINGLE
mpi4py.MPI.THREAD_SINGLE: int = THREAD_SINGLE
constant THREAD_SINGLE, type int <https://docs.python.org/3/library/functions.html#int>. single-threaded and single, but never alone โ she has int <https://docs.python.org/3/library/functions.html#int> energy. ๐ซถ
๐ mpi4py.MPI.THREAD_FUNNELED
mpi4py.MPI.THREAD_FUNNELED: int = THREAD_FUNNELED
constant THREAD_FUNNELED โ int <https://docs.python.org/3/library/functions.html#int>. funneled right into the integer pipeline. ๐
๐ mpi4py.MPI.THREAD_SERIALIZED
mpi4py.MPI.THREAD_SERIALIZED: int = THREAD_SERIALIZED
constant THREAD_SERIALIZED, of type int <https://docs.python.org/3/library/functions.html#int>. serialized, sanitized, still an integer. ๐
๐ mpi4py.MPI.THREAD_MULTIPLE
mpi4py.MPI.THREAD_MULTIPLE: int = THREAD_MULTIPLE
constant THREAD_MULTIPLE, type int <https://docs.python.org/3/library/functions.html#int>. multiple threads, multiple vibes, one int. ๐ฅ
๐ mpi4py.MPI.VERSION
mpi4py.MPI.VERSION: int = VERSION
constant VERSION, and she is an int <https://docs.python.org/3/library/functions.html#int>. the version constant, doing version constant things, as an integer. โจ
๐ mpi4py.MPI.SUBVERSION
mpi4py.MPI.SUBVERSION: int = SUBVERSION
constant SUBVERSION โ int <https://docs.python.org/3/library/functions.html#int>. subversion here means "the sub-part of the version," not the other thing, bestie. ๐ธ
๐ mpi4py.MPI.MAX_PROCESSOR_NAME
mpi4py.MPI.MAX_PROCESSOR_NAME: int = MAX_PROCESSOR_NAME
constant MAX_PROCESSOR_NAME, of type int <https://docs.python.org/3/library/functions.html#int>. a MAX constant, and yes it's an integer. ๐
๐ mpi4py.MPI.MAX_ERROR_STRING
mpi4py.MPI.MAX_ERROR_STRING: int = MAX_ERROR_STRING
constant MAX_ERROR_STRING, type int <https://docs.python.org/3/library/functions.html#int>. max error string length vibes, integer body. ๐ฆ
๐ mpi4py.MPI.MAX_PORT_NAME
mpi4py.MPI.MAX_PORT_NAME: int = MAX_PORT_NAME
constant MAX_PORT_NAME โ int <https://docs.python.org/3/library/functions.html#int>. a max, a name, a port, an int. the whole package. ๐
๐ mpi4py.MPI.MAX_INFO_KEY
mpi4py.MPI.MAX_INFO_KEY: int = MAX_INFO_KEY
constant MAX_INFO_KEY, of type int <https://docs.python.org/3/library/functions.html#int>. the key to the max info, and the key is an integer. ๐
๐ mpi4py.MPI.MAX_INFO_VAL
mpi4py.MPI.MAX_INFO_VAL: int = MAX_INFO_VAL
constant MAX_INFO_VAL, type int <https://docs.python.org/3/library/functions.html#int>. the value half of the pair above, equally an int. ๐
๐ mpi4py.MPI.MAX_OBJECT_NAME
mpi4py.MPI.MAX_OBJECT_NAME: int = MAX_OBJECT_NAME
constant MAX_OBJECT_NAME โ int <https://docs.python.org/3/library/functions.html#int>. max object name, main character name, integer type. ๐
๐ mpi4py.MPI.MAX_DATAREP_STRING
mpi4py.MPI.MAX_DATAREP_STRING: int = MAX_DATAREP_STRING
constant MAX_DATAREP_STRING, of type int <https://docs.python.org/3/library/functions.html#int>. datarep string max, integer always. ๐
๐ mpi4py.MPI.MAX_LIBRARY_VERSION_STRING
mpi4py.MPI.MAX_LIBRARY_VERSION_STRING: int = MAX_LIBRARY_VERSION_STRING
constant MAX_LIBRARY_VERSION_STRING, type int <https://docs.python.org/3/library/functions.html#int>. the longest-named MAX in this batch and, you guessed it, an integer. not me being obsessed with how consistent she is ๐
okay bestie we're still in the constants zone and honestly? the datatype roster is iconic โ every single one of these is a module-level name living in mpi4py.MPI, and you're getting all of them, no skips, no edits, periodt ๐
mpi4py.MPI.MAX_PSET_NAME_LENโ declared asmpi4py.MPI.MAX_PSET_NAME_LEN: int = MAX_PSET_NAME_LEN. It's a constant namedMAX_PSET_NAME_LENwhose type isint. ๐mpi4py.MPI.MAX_STRINGTAG_LENโ declared asmpi4py.MPI.MAX_STRINGTAG_LEN: int = MAX_STRINGTAG_LEN. A constant namedMAX_STRINGTAG_LEN, typeint. โจ
and now the datatype girlies โ every one of these is an object of type <code>Datatype</code>, fr fr ๐ฆ
mpi4py.MPI.DATATYPE_NULLโmpi4py.MPI.DATATYPE_NULL: Datatype = DATATYPE_NULL. ObjectDATATYPE_NULL, typeDatatype.mpi4py.MPI.PACKEDโmpi4py.MPI.PACKED: Datatype = PACKED. ObjectPACKED, typeDatatype.mpi4py.MPI.BYTEโmpi4py.MPI.BYTE: Datatype = BYTE. ObjectBYTE, typeDatatype.mpi4py.MPI.AINTโmpi4py.MPI.AINT: Datatype = AINT. ObjectAINT, typeDatatype.mpi4py.MPI.OFFSETโmpi4py.MPI.OFFSET: Datatype = OFFSET. ObjectOFFSET, typeDatatype.mpi4py.MPI.COUNTโmpi4py.MPI.COUNT: Datatype = COUNT. ObjectCOUNT, typeDatatype.
the classic C-flavoured crew, showing up one by one like it's a group photo ๐ธ
mpi4py.MPI.CHARโmpi4py.MPI.CHAR: Datatype = CHAR. ObjectCHAR, typeDatatype.mpi4py.MPI.WCHARโmpi4py.MPI.WCHAR: Datatype = WCHAR. ObjectWCHAR, typeDatatype.mpi4py.MPI.SIGNED_CHARโmpi4py.MPI.SIGNED_CHAR: Datatype = SIGNED_CHAR. ObjectSIGNED_CHAR, typeDatatype.mpi4py.MPI.SHORTโmpi4py.MPI.SHORT: Datatype = SHORT. ObjectSHORT, typeDatatype.mpi4py.MPI.INTโmpi4py.MPI.INT: Datatype = INT. ObjectINT, typeDatatype.mpi4py.MPI.LONGโmpi4py.MPI.LONG: Datatype = LONG. ObjectLONG, typeDatatype.mpi4py.MPI.LONG_LONGโmpi4py.MPI.LONG_LONG: Datatype = LONG_LONG. ObjectLONG_LONG, typeDatatype.mpi4py.MPI.UNSIGNED_CHARโmpi4py.MPI.UNSIGNED_CHAR: Datatype = UNSIGNED_CHAR. ObjectUNSIGNED_CHAR, typeDatatype.mpi4py.MPI.UNSIGNED_SHORTโmpi4py.MPI.UNSIGNED_SHORT: Datatype = UNSIGNED_SHORT. ObjectUNSIGNED_SHORT, typeDatatype.mpi4py.MPI.UNSIGNEDโmpi4py.MPI.UNSIGNED: Datatype = UNSIGNED. ObjectUNSIGNED, typeDatatype.mpi4py.MPI.UNSIGNED_LONGโmpi4py.MPI.UNSIGNED_LONG: Datatype = UNSIGNED_LONG. ObjectUNSIGNED_LONG, typeDatatype.mpi4py.MPI.UNSIGNED_LONG_LONGโmpi4py.MPI.UNSIGNED_LONG_LONG: Datatype = UNSIGNED_LONG_LONG. ObjectUNSIGNED_LONG_LONG, typeDatatype.
floating point era ๐ญ they're all so pretty and so specific
mpi4py.MPI.FLOATโmpi4py.MPI.FLOAT: Datatype = FLOAT. ObjectFLOAT, typeDatatype.mpi4py.MPI.DOUBLEโmpi4py.MPI.DOUBLE: Datatype = DOUBLE. ObjectDOUBLE, typeDatatype.mpi4py.MPI.LONG_DOUBLEโmpi4py.MPI.LONG_DOUBLE: Datatype = LONG_DOUBLE. ObjectLONG_DOUBLE, typeDatatype.
now the <code>_t</code> family โ fixed-width besties, lowkey the ones you actually reach for ๐
mpi4py.MPI.C_BOOLโmpi4py.MPI.C_BOOL: Datatype = C_BOOL. ObjectC_BOOL, typeDatatype.mpi4py.MPI.INT8_Tโmpi4py.MPI.INT8_T: Datatype = INT8_T. ObjectINT8_T, typeDatatype.mpi4py.MPI.INT16_Tโmpi4py.MPI.INT16_T: Datatype = INT16_T. ObjectINT16_T, typeDatatype.mpi4py.MPI.INT32_Tโmpi4py.MPI.INT32_T: Datatype = INT32_T. ObjectINT32_T, typeDatatype.mpi4py.MPI.INT64_Tโmpi4py.MPI.INT64_T: Datatype = INT64_T. ObjectINT64_T, typeDatatype.mpi4py.MPI.UINT8_Tโmpi4py.MPI.UINT8_T: Datatype = UINT8_T. ObjectUINT8_T, typeDatatype.mpi4py.MPI.UINT16_Tโmpi4py.MPI.UINT16_T: Datatype = UINT16_T. ObjectUINT16_T, typeDatatype.mpi4py.MPI.UINT32_Tโmpi4py.MPI.UINT32_T: Datatype = UINT32_T. ObjectUINT32_T, typeDatatype.mpi4py.MPI.UINT64_Tโmpi4py.MPI.UINT64_T: Datatype = UINT64_T. ObjectUINT64_T, typeDatatype.mpi4py.MPI.FLOAT16_Tโmpi4py.MPI.FLOAT16_T: Datatype = FLOAT16_T. ObjectFLOAT16_T, typeDatatype.mpi4py.MPI.FLOAT32_Tโmpi4py.MPI.FLOAT32_T: Datatype = FLOAT32_T. ObjectFLOAT32_T, typeDatatype.mpi4py.MPI.FLOAT64_Tโmpi4py.MPI.FLOAT64_T: Datatype = FLOAT64_T. ObjectFLOAT64_T, typeDatatype.mpi4py.MPI.BFLOAT16_Tโmpi4py.MPI.BFLOAT16_T: Datatype = BFLOAT16_T. ObjectBFLOAT16_T, typeDatatype.
complex number moment ๐ง stay with me, we're not even halfway through the list
mpi4py.MPI.C_COMPLEXโmpi4py.MPI.C_COMPLEX: Datatype = C_COMPLEX. ObjectC_COMPLEX, typeDatatype.mpi4py.MPI.C_FLOAT_COMPLEXโmpi4py.MPI.C_FLOAT_COMPLEX: Datatype = C_FLOAT_COMPLEX. ObjectC_FLOAT_COMPLEX, typeDatatype.mpi4py.MPI.C_DOUBLE_COMPLEXโmpi4py.MPI.C_DOUBLE_COMPLEX: Datatype = C_DOUBLE_COMPLEX. ObjectC_DOUBLE_COMPLEX, typeDatatype.mpi4py.MPI.C_LONG_DOUBLE_COMPLEXโmpi4py.MPI.C_LONG_DOUBLE_COMPLEX: Datatype = C_LONG_DOUBLE_COMPLEX. ObjectC_LONG_DOUBLE_COMPLEX, typeDatatype.
and the C++ remix, same energy, different name ๐
mpi4py.MPI.CXX_BOOLโmpi4py.MPI.CXX_BOOL: Datatype = CXX_BOOL. ObjectCXX_BOOL, typeDatatype.mpi4py.MPI.CXX_FLOAT_COMPLEXโmpi4py.MPI.CXX_FLOAT_COMPLEX: Datatype = CXX_FLOAT_COMPLEX. ObjectCXX_FLOAT_COMPLEX, typeDatatype.mpi4py.MPI.CXX_DOUBLE_COMPLEXโmpi4py.MPI.CXX_DOUBLE_COMPLEX: Datatype = CXX_DOUBLE_COMPLEX. ObjectCXX_DOUBLE_COMPLEX, typeDatatype.mpi4py.MPI.CXX_LONG_DOUBLE_COMPLEXโmpi4py.MPI.CXX_LONG_DOUBLE_COMPLEX: Datatype = CXX_LONG_DOUBLE_COMPLEX. ObjectCXX_LONG_DOUBLE_COMPLEX, typeDatatype.
the two-for-one bundles ๐ซถ pairs, but make them a datatype
mpi4py.MPI.SHORT_INTโmpi4py.MPI.SHORT_INT: Datatype = SHORT_INT. ObjectSHORT_INT, typeDatatype.mpi4py.MPI.INT_INTโmpi4py.MPI.INT_INT: Datatype = INT_INT. ObjectINT_INT, typeDatatype.mpi4py.MPI.TWOINTโmpi4py.MPI.TWOINT: Datatype = TWOINT. ObjectTWOINT, typeDatatype.mpi4py.MPI.LONG_INTโmpi4py.MPI.LONG_INT: Datatype = LONG_INT. ObjectLONG_INT, typeDatatype.mpi4py.MPI.FLOAT_INTโmpi4py.MPI.FLOAT_INT: Datatype = FLOAT_INT. ObjectFLOAT_INT, typeDatatype.mpi4py.MPI.DOUBLE_INTโmpi4py.MPI.DOUBLE_INT: Datatype = DOUBLE_INT. ObjectDOUBLE_INT, typeDatatype.mpi4py.MPI.LONG_DOUBLE_INTโmpi4py.MPI.LONG_DOUBLE_INT: Datatype = LONG_DOUBLE_INT. ObjectLONG_DOUBLE_INT, typeDatatype.
Fortran girlies, this is your section, we love you ๐
mpi4py.MPI.CHARACTERโmpi4py.MPI.CHARACTER: Datatype = CHARACTER. ObjectCHARACTER, typeDatatype.mpi4py.MPI.LOGICALโmpi4py.MPI.LOGICAL: Datatype = LOGICAL. ObjectLOGICAL, typeDatatype.mpi4py.MPI.INTEGERโmpi4py.MPI.INTEGER: Datatype = INTEGER. ObjectINTEGER, typeDatatype.mpi4py.MPI.REALโmpi4py.MPI.REAL: Datatype = REAL. ObjectREAL, typeDatatype.mpi4py.MPI.DOUBLE_PRECISIONโmpi4py.MPI.DOUBLE_PRECISION: Datatype = DOUBLE_PRECISION. ObjectDOUBLE_PRECISION, typeDatatype.mpi4py.MPI.COMPLEXโmpi4py.MPI.COMPLEX: Datatype = COMPLEX. ObjectCOMPLEX, typeDatatype.mpi4py.MPI.DOUBLE_COMPLEXโmpi4py.MPI.DOUBLE_COMPLEX: Datatype = DOUBLE_COMPLEX. ObjectDOUBLE_COMPLEX, typeDatatype.
and the sized Fortran variants, numbered like they're in a lineup โจ
mpi4py.MPI.LOGICAL1โmpi4py.MPI.LOGICAL1: Datatype = LOGICAL1. ObjectLOGICAL1, typeDatatype.mpi4py.MPI.LOGICAL2โmpi4py.MPI.LOGICAL2: Datatype = LOGICAL2. ObjectLOGICAL2, typeDatatype.mpi4py.MPI.LOGICAL4โmpi4py.MPI.LOGICAL4: Datatype = LOGICAL4. ObjectLOGICAL4, typeDatatype.mpi4py.MPI.LOGICAL8โmpi4py.MPI.LOGICAL8: Datatype = LOGICAL8. ObjectLOGICAL8, typeDatatype.mpi4py.MPI.LOGICAL16โmpi4py.MPI.LOGICAL16: Datatype = LOGICAL16. ObjectLOGICAL16, typeDatatype.mpi4py.MPI.INTEGER1โmpi4py.MPI.INTEGER1: Datatype = INTEGER1. ObjectINTEGER1, typeDatatype.mpi4py.MPI.INTEGER2โmpi4py.MPI.INTEGER2: Datatype = INTEGER2. ObjectINTEGER2, typeDatatype.mpi4py.MPI.INTEGER4โmpi4py.MPI.INTEGER4: Datatype = INTEGER4. ObjectINTEGER4, typeDatatype.mpi4py.MPI.INTEGER8โmpi4py.MPI.INTEGER8: Datatype = INTEGER8. ObjectINTEGER8, typeDatatype.mpi4py.MPI.INTEGER16โmpi4py.MPI.INTEGER16: Datatype = INTEGER16. ObjectINTEGER16, typeDatatype.
and that's the whole datatype lineup bestie, every name exactly where it belongs, no notes ๐
๐ mpi4py.MPI.REAL2 ๐
mpi4py.MPI.REAL2: Datatype = REAL2- Object
REAL2of typeDatatype(mpi4py.MPI.Datatype)
โจ mpi4py.MPI.REAL4 โจ
mpi4py.MPI.REAL4: Datatype = REAL4- Object
REAL4of typeDatatype(mpi4py.MPI.Datatype)
๐ธ mpi4py.MPI.REAL8 ๐ธ
mpi4py.MPI.REAL8: Datatype = REAL8- Object
REAL8of typeDatatype(mpi4py.MPI.Datatype)
๐ฆ mpi4py.MPI.REAL16 ๐ฆ
mpi4py.MPI.REAL16: Datatype = REAL16- Object
REAL16of typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.COMPLEX4 ๐
mpi4py.MPI.COMPLEX4: Datatype = COMPLEX4- Object
COMPLEX4of typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.COMPLEX8 ๐
mpi4py.MPI.COMPLEX8: Datatype = COMPLEX8- Object
COMPLEX8of typeDatatype(mpi4py.MPI.Datatype)
โญ mpi4py.MPI.COMPLEX16 โญ
mpi4py.MPI.COMPLEX16: Datatype = COMPLEX16- Object
COMPLEX16of typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.COMPLEX32 ๐
mpi4py.MPI.COMPLEX32: Datatype = COMPLEX32- Object
COMPLEX32of typeDatatype(mpi4py.MPI.Datatype)
๐ฟ mpi4py.MPI.UNSIGNED_INT ๐ฟ
mpi4py.MPI.UNSIGNED_INT: Datatype = UNSIGNED_INT- Object
UNSIGNED_INTof typeDatatype(mpi4py.MPI.Datatype)
๐
mpi4py.MPI.SIGNED_SHORT ๐
mpi4py.MPI.SIGNED_SHORT: Datatype = SIGNED_SHORT- Object
SIGNED_SHORTof typeDatatype(mpi4py.MPI.Datatype)
๐ฎ mpi4py.MPI.SIGNED_INT ๐ฎ
mpi4py.MPI.SIGNED_INT: Datatype = SIGNED_INT- Object
SIGNED_INTof typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.SIGNED_LONG ๐
mpi4py.MPI.SIGNED_LONG: Datatype = SIGNED_LONG- Object
SIGNED_LONGof typeDatatype(mpi4py.MPI.Datatype)
๐ง mpi4py.MPI.SIGNED_LONG_LONG ๐ง
mpi4py.MPI.SIGNED_LONG_LONG: Datatype = SIGNED_LONG_LONG- Object
SIGNED_LONG_LONGof typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.BOOL ๐
mpi4py.MPI.BOOL: Datatype = BOOL- Object
BOOLof typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.SINT8_T ๐
mpi4py.MPI.SINT8_T: Datatype = SINT8_T- Object
SINT8_Tof typeDatatype(mpi4py.MPI.Datatype)
๐ชฉ mpi4py.MPI.SINT16_T ๐ชฉ
mpi4py.MPI.SINT16_T: Datatype = SINT16_T- Object
SINT16_Tof typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.SINT32_T ๐
mpi4py.MPI.SINT32_T: Datatype = SINT32_T- Object
SINT32_Tof typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.SINT64_T ๐
mpi4py.MPI.SINT64_T: Datatype = SINT64_T- Object
SINT64_Tof typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.F_BOOL ๐
mpi4py.MPI.F_BOOL: Datatype = F_BOOL- Object
F_BOOLof typeDatatype(mpi4py.MPI.Datatype)
๐ฑ mpi4py.MPI.F_INT ๐ฑ
mpi4py.MPI.F_INT: Datatype = F_INT- Object
F_INTof typeDatatype(mpi4py.MPI.Datatype)
๐ง mpi4py.MPI.F_FLOAT ๐ง
mpi4py.MPI.F_FLOAT: Datatype = F_FLOAT- Object
F_FLOATof typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.F_DOUBLE ๐
mpi4py.MPI.F_DOUBLE: Datatype = F_DOUBLE- Object
F_DOUBLEof typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.F_COMPLEX ๐
mpi4py.MPI.F_COMPLEX: Datatype = F_COMPLEX- Object
F_COMPLEXof typeDatatype(mpi4py.MPI.Datatype)
๐ซง mpi4py.MPI.F_FLOAT_COMPLEX ๐ซง
mpi4py.MPI.F_FLOAT_COMPLEX: Datatype = F_FLOAT_COMPLEX- Object
F_FLOAT_COMPLEXof typeDatatype(mpi4py.MPI.Datatype)
๐ mpi4py.MPI.F_DOUBLE_COMPLEX ๐
mpi4py.MPI.F_DOUBLE_COMPLEX: Datatype = F_DOUBLE_COMPLEX- Object
F_DOUBLE_COMPLEXof typeDatatype(mpi4py.MPI.Datatype)
โ๏ธ mpi4py.MPI.REQUEST_NULL โ๏ธ
mpi4py.MPI.REQUEST_NULL: Request = REQUEST_NULL- Object
REQUEST_NULLof typeRequest(mpi4py.MPI.Request)
๐ mpi4py.MPI.MESSAGE_NULL ๐
mpi4py.MPI.MESSAGE_NULL: Message = MESSAGE_NULL- Object
MESSAGE_NULLof typeMessage(mpi4py.MPI.Message)
๐ญ mpi4py.MPI.MESSAGE_NO_PROC ๐ญ
mpi4py.MPI.MESSAGE_NO_PROC: Message = MESSAGE_NO_PROC- Object
MESSAGE_NO_PROCof typeMessage(mpi4py.MPI.Message)
๐ mpi4py.MPI.OP_NULL ๐
mpi4py.MPI.OP_NULL: Op = OP_NULL- Object
OP_NULLof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ฅ mpi4py.MPI.MAX ๐ฅ
mpi4py.MPI.MAX: Op = MAX- Object
MAXof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ mpi4py.MPI.MIN ๐
mpi4py.MPI.MIN: Op = MIN- Object
MINof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
โ mpi4py.MPI.SUM โ
mpi4py.MPI.SUM: Op = SUM- Object
SUMof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
โ๏ธ mpi4py.MPI.PROD โ๏ธ
mpi4py.MPI.PROD: Op = PROD- Object
PRODof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ mpi4py.MPI.LAND ๐
mpi4py.MPI.LAND: Op = LAND- Object
LANDof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐งฉ mpi4py.MPI.BAND ๐งฉ
mpi4py.MPI.BAND: Op = BAND- Object
BANDof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ฟ mpi4py.MPI.LOR ๐ฟ
mpi4py.MPI.LOR: Op = LOR- Object
LORof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
โ๏ธ mpi4py.MPI.BOR โ๏ธ
mpi4py.MPI.BOR: Op = BOR- Object
BORof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ mpi4py.MPI.LXOR ๐
mpi4py.MPI.LXOR: Op = LXOR- Object
LXORof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ท mpi4py.MPI.BXOR ๐ท
mpi4py.MPI.BXOR: Op = BXOR- Object
BXORof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ mpi4py.MPI.MAXLOC ๐
mpi4py.MPI.MAXLOC: Op = MAXLOC- Object
MAXLOCof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ mpi4py.MPI.MINLOC ๐
mpi4py.MPI.MINLOC: Op = MINLOC- Object
MINLOCof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ mpi4py.MPI.REPLACE ๐
mpi4py.MPI.REPLACE: Op = REPLACE- Object
REPLACEof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ซ mpi4py.MPI.NO_OP ๐ซ
mpi4py.MPI.NO_OP: Op = NO_OP- Object
NO_OPof typeOp(mpi4py.MPI.Op)
Parameters
x(Any)y(Any)
Return type: Any
๐ณ๏ธ mpi4py.MPI.GROUP_NULL ๐ณ๏ธ
mpi4py.MPI.GROUP_NULL: Group = GROUP_NULL- Object
GROUP_NULLof typeGroup(mpi4py.MPI.Group)
๐ซฅ mpi4py.MPI.GROUP_EMPTY ๐ซฅ
mpi4py.MPI.GROUP_EMPTY: Group = GROUP_EMPTY- Object
GROUP_EMPTYof typeGroup(mpi4py.MPI.Group)
๐ญ mpi4py.MPI.INFO_NULL ๐ญ
mpi4py.MPI.INFO_NULL: Info = INFO_NULL- Object
INFO_NULLof typeInfo(mpi4py.MPI.Info)
๐ mpi4py.MPI.INFO_ENV ๐
mpi4py.MPI.INFO_ENV: Info = INFO_ENV- Object
INFO_ENVof typeInfo(mpi4py.MPI.Info)
๐งฏ mpi4py.MPI.ERRHANDLER_NULL ๐งฏ
mpi4py.MPI.ERRHANDLER_NULL: Errhandler = ERRHANDLER_NULL- Object
ERRHANDLER_NULLof typeErrhandler(mpi4py.MPI.Errhandler)
โฉ๏ธ mpi4py.MPI.ERRORS_RETURN โฉ๏ธ
mpi4py.MPI.ERRORS_RETURN: Errhandler = ERRORS_RETURN- Object
ERRORS_RETURNof typeErrhandler(mpi4py.MPI.Errhandler)
๐ mpi4py.MPI.ERRORS_ABORT ๐
mpi4py.MPI.ERRORS_ABORT: Errhandler = ERRORS_ABORT- Object
ERRORS_ABORTof typeErrhandler(mpi4py.MPI.Errhandler)
๐ mpi4py.MPI.ERRORS_ARE_FATAL ๐
mpi4py.MPI.ERRORS_ARE_FATAL: Errhandler = ERRORS_ARE_FATAL- Object
ERRORS_ARE_FATALof typeErrhandler(mpi4py.MPI.Errhandler)
๐ฑ mpi4py.MPI.SESSION_NULL ๐ฑ
mpi4py.MPI.SESSION_NULL: Session = SESSION_NULL- Object
SESSION_NULLof typeSession(mpi4py.MPI.Session)
๐ซง mpi4py.MPI.COMM_NULL ๐ซง
mpi4py.MPI.COMM_NULL: Comm = COMM_NULL- Object
COMM_NULLof typeComm(mpi4py.MPI.Comm)
๐ช mpi4py.MPI.COMM_SELF ๐ช
mpi4py.MPI.COMM_SELF: Intracomm = COMM_SELF- Object
COMM_SELFof typeIntracomm(mpi4py.MPI.Intracomm)
๐ mpi4py.MPI.COMM_WORLD ๐
mpi4py.MPI.COMM_WORLD: Intracomm = COMM_WORLD- Object
COMM_WORLDof typeIntracomm(mpi4py.MPI.Intracomm)
๐ช mpi4py.MPI.WIN_NULL ๐ช
mpi4py.MPI.WIN_NULL: Win = WIN_NULL- Object
WIN_NULLof typeWin(mpi4py.MPI.Win)
๐ mpi4py.MPI.FILE_NULL ๐
mpi4py.MPI.FILE_NULL: File = FILE_NULL- Object
FILE_NULLof typeFile(mpi4py.MPI.File)
โฌ๏ธ mpi4py.MPI.BOTTOM โฌ๏ธ
mpi4py.MPI.BOTTOM: BottomType = BOTTOM- Object
BOTTOMof typeBottomType(mpi4py.MPI.BottomType)
๐ mpi4py.MPI.IN_PLACE ๐
mpi4py.MPI.IN_PLACE: InPlaceType = IN_PLACE- Object
IN_PLACEof typeInPlaceType(mpi4py.MPI.InPlaceType)
โจ mpi4py.MPI.BUFFER_AUTOMATIC โจ
mpi4py.MPI.BUFFER_AUTOMATIC: BufferAutomaticType = BUFFER_AUTOMATIC- Object
BUFFER_AUTOMATICof typeBufferAutomaticType(mpi4py.MPI.BufferAutomaticType) mpi4py.MPI.pickleโ okay bestie, this is literally the module-level thing:mpi4py.MPI.pickle๐ it's typed asPickle(as in thempi4py.MPI.Pickleobject type, iykyk), and it's an instance of thePickleobject class. That's it. That's the whole vibe. โจ
๐ CITATION ๐
okay so if MPI for Python has been a whole significant moment for a project of yours that ends up in an academic publication?? please please please acknowledge it, bestie, it's giving respect-the-queens energy ๐ here's the receipts:
- M. Rogowski, S. Aseeri, D. Keyes, and L. Dalcin, mpi4py.futures: MPI-Based Asynchronous Task Execution for Python, IEEE Transactions on Parallel and Distributed Systems, 34(2):611-622, 2023. <https://doi.org/10.1109/TPDS.2022.3225481>
- L. Dalcin and Y.-L. L. Fang, mpi4py: Status Update After 12 Years of Development, Computing in Science & Engineering, 23(4):47-54, 2021. <https://doi.org/10.1109/MCSE.2021.3083216>
- L. Dalcin, P. Kler, R. Paz, and A. Cosimo, Parallel Distributed Computing using Python, Advances in Water Resources, 34(9):1124-1139, 2011. <https://doi.org/10.1016/j.advwatres.2011.04.013>
- L. Dalcin, R. Paz, M. Storti, and J. DโElia, MPI for Python: performance improvements and MPI-2 extensions, Journal of Parallel and Distributed Computing, 68(5):655-662, 2008. <https://doi.org/10.1016/j.jpdc.2007.09.005>
- L. Dalcin, R. Paz, and M. Storti, MPI for Python, Journal of Parallel and Distributed Computing, 65(9):1108-1115, 2005. <https://doi.org/10.1016/j.jpdc.2005.03.010>
๐ INSTALLATION ๐
โจ Wheel packages โจ
The mpi4py project builds and publishes binary wheels that can run across a whole buffet of things, no cap:
- operating systems: Linux, macOS, Windows;
- processor architectures: AMD64, ARM64;
- MPI implementations: MPICH, Open MPI, MVAPICH, Intel MPI, HPE Cray MPICH, Microsoft MPI;
- Python implementations: CPython, PyPy.
These mpi4py wheels are distributed via the Python Package Index (PyPI <https://pypi.org/project/mpi4py/>) and honestly you can just install them with Python package managers like pip <https://pip.pypa.io>, like:
python -m pip install mpi4py
The mpi4py wheels can be installed in standard Python virtual environments, fr fr. And plot twist: the MPI runtime can be provided by other wheels installed in that same virtual environment. ๐
Tip: Intel publishes production-grade Intel MPI wheels <https://pypi.org/project/impi-rt/#files> for Linux (x86_64) and Windows (AMD64). mpi4py and MPI wheels can be installed side by side to get a ready-to-use Python+MPI environment, bestie:
python -m pip install mpi4py impi-rt
Tip: The mpi4py project publishes MPICH wheels <https://pypi.org/project/mpich/#files> and Open MPI wheels <https://pypi.org/project/openmpi/#files> for Linux (x86_64/aarch64) and macOS (arm64/x86_64). mpi4py and MPI wheels can be installed side by side to get a ready-to-use Python+MPI environment:
python -m pip install mpi4py mpich # for MPICH
python -m pip install mpi4py openmpi # for Open MPI
Warning: โ ๏ธ The MPI wheels are distributed with special focus on ease of use, convenience, compatibility, and interoperability. The Linux wheels are built in somewhat constrained environments with relatively dated Linux distributions (manylinux <https://github.com/pypa/manylinux> container images). So like, they may lack support for features like GPU awareness (CUDA/ROCm) and C++/Fortran bindings. In production scenarios, it is recommended to use external (either custom-built or system-provided) MPI installations. Periodt. ๐
The mpi4py wheels can also be installed (with pip <https://pip.pypa.io>) in conda <https://docs.conda.io> environments and they should work out of the box, without any special tweak to environment variables, for any of the MPI packages provided by conda-forge <https://conda-forge.org/>. Iconic. โจ
Externally-provided MPI implementations may come from a system package manager, sysadmin-maintained builds accessible via module files, or customized user builds. Such usage is supported and encouraged, lowkey. However, there are a few platform-specific considerations to take into account. ๐
๐ธ Linux ๐ธ
The Linux (x86_64/aarch64) wheels require one of:
- MPICH <https://mpich.org> or any other ABI-compatible derivative, like MVAPICH <https://mvapich.cse.ohio-state.edu>, Intel MPI <https://software.intel.com/intel-mpi-library>, HPE Cray MPICH <https://cpe.ext.hpe.com/docs/latest/mpt/mpich/>
- Open MPI <https://open-mpi.org> or any other ABI-compatible derivative, like NVIDIA HPC-X <https://developer.nvidia.com/networking/hpc-x>
Users may need to set the LD_LIBRARY_PATH environment variable such that the dynamic linker is able to find at runtime the MPI shared library file (libmpi.so.*). iykyk ๐
๐ Fedora/RHEL ๐
On Fedora/RHEL systems, both MPICH and Open MPI are available for installation. There is no default or preferred MPI implementation, bestie โ instead, users must select their favorite MPI implementation by loading the proper MPI module:
module load mpi/mpich-$(arch) # for MPICH
module load mpi/openmpi-$(arch) # for Open MPI
After loading the requested MPI module, the LD_LIBRARY_PATH environment variable should be properly setup. slay โจ
๐ฆ Debian/Ubuntu ๐ฆ
On Debian/Ubuntu systems, Open MPI is the default MPI implementation and most of the MPI-based applications and libraries provided by the distribution depend on Open MPI. Nonetheless, MPICH is also available to users for installation.
In Ubuntu 22.04 and older, due to legacy reasons, the MPICH ABI is slightly broken: the MPI shared library file is named libmpich.so.12 instead of libmpi.so.12 as required by the MPICH ABI Compatibility Initiative <https://www.mpich.org/abi/>. not me crying over ABI drama ๐ญ
Users without sudo access can workaround this issue creating a symbolic link anywhere in their home directory and appending to LD_LIBRARY_PATH:
mkdir -p ~/.local/lib
libdir=/usr/lib/$(arch)-linux-gnu
ln -s $libdir/libmpich.so.12 ~/.local/lib/libmpi.so.12
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/.local/lib
A system-wide fix for all users requires sudo access:
libdir=/usr/lib/$(arch)-linux-gnu
sudo ln -sr $libdir/libmpi{ch,}.so.12
๐ HPE Cray OS ๐
On HPE Cray systems, users must load the cray-mpich-abi module. For further details, refer to man intro_mpi <https://cpe.ext.hpe.com/docs/latest/mpt/mpich/intro_mpi.html#using-mpich-abi-compatibility>. ๐
โญ macOS โญ
The macOS (arm64/x86_64) wheels require:
- MPICH <https://mpich.org> or Open MPI <https://open-mpi.org> installed (either manually or via a package manager) in the standard system prefix
/usr/local - MPICH <https://mpich.org> or Open MPI <https://open-mpi.org> installed via Homebrew <https://brew.sh/> in the default prefix
/opt/homebrew - MPICH <https://mpich.org> or Open MPI <https://open-mpi.org> installed via MacPorts <https://www.macports.org/> in the default prefix
/opt/local
๐ซถ Windows ๐ซถ
The Windows (AMD64) wheels require one of:
- Intel MPI <https://software.intel.com/intel-mpi-library>
- Microsoft MPI <https://learn.microsoft.com/message-passing-interface/microsoft-mpi>
User may need to set the I_MPI_ROOT or MSMPI_BIN environment variables such that the MPI dynamic link library (DLL) (impi.dll or msmpi.dll) can be found at runtime. ๐
Intel MPI is under active development and supports recent versions of the MPI standard. Intel MPI can be installed with pip (see the impi-rt <https://pypi.org/project/impi-rt/> package on PyPI), being therefore straightforward to get it up and running within a Python environment. Intel MPI can also be installed system-wide as part of the Intel oneAPI HPC Toolkit for Windows or via standalone online/offline installers. ate, no crumbs โจ
๐ Conda packages ๐
The conda-forge <https://conda-forge.org/> community provides ready-to-use binary packages from an ever growing collection of software libraries built around the multi-platform conda package manager. Four MPI implementations are available on conda-forge: Open MPI (Linux and macOS), MPICH (Linux and macOS), Intel MPI (Linux and Windows), and Microsoft MPI (Windows). You can install mpi4py and your preferred MPI implementation using the conda <https://docs.conda.io> package manager:
- to use MPICH do:
conda install -c conda-forge mpi4py mpich
- to use Open MPI do:
conda install -c conda-forge mpi4py openmpi
- to use Intel MPI do:
conda install -c conda-forge mpi4py impi_rt
- to use Microsoft MPI do:
conda install -c conda-forge mpi4py msmpi
MPICH and many of its derivatives are ABI-compatible. You can provide the package specification mpich=X.Y.*=external_* (where X and Y are the major and minor version numbers) to request the conda package manager to use system-provided MPICH (or derivative) libraries. Similarly, you can provide the package specification openmpi=X.Y.*=external_* to use system-provided Open MPI libraries. bestie that's the whole game ๐ฅ
The openmpi package on conda-forge has built-in CUDA support, but it is disabled by default. To enable it, follow the instruction outlined during conda install. Additionally, UCX support is also available once the ucx package is installed.
Warning: โ ๏ธ The MPI conda-forge packages are built with special focus on compatibility. The MPICH and Open MPI packages are built in a constrained environment with relatively dated OS images. Therefore, they may lack support for high-performance features like cross-memory attach (XPMEM/CMA). In production scenarios, it is recommended to use external (either custom-built or system-provided) MPI installations. See the relevant conda-forge documentation about using external MPI libraries <https://conda-forge.org/docs/user/tipsandtricks/#using-external-message-passing-interface-mpi-libraries> . ๐
๐ง System packages ๐ง
mpi4py is readily available through system package managers of most Linux distributions and the most popular community package managers for macOS. iconic โจ
๐ธ Linux ๐ธ
On Fedora Linux systems (as well as RHEL and their derivatives using the EPEL software repository), you can install binary packages with the system package manager:
- using
dnfand thempichpackage:
sudo dnf install python3-mpi4py-mpich
- using
dnfand theopenmpipackage:
sudo dnf install python3-mpi4py-openmpi
Please remember to load the correct MPI module for your chosen MPI implementation:
- for the
mpichpackage do:
module load mpi/mpich-$(arch)
python -c "from mpi4py import MPI"
- for the
openmpipackage do:
module load mpi/openmpi-$(arch)
python -c "from mpi4py import MPI"
On Ubuntu Linux and Debian Linux systems, binary packages are available for installation using the system package manager:
sudo apt install python3-mpi4py
๐ On Arch Linux, bestie
Binary packages? Already there, and you can grab them with the system package manager, like:
sudo pacman -S python-mpi4py
Slay. That's it. That's the whole thing. ๐
๐ macOS girlies, this one's for you
macOS users can install mpi4py using the Homebrew <https://brew.sh/> package manager:
brew install mpi4py
Heads up though โ the Homebrew mpi4py package uses Open MPI. Alternatively, install the mpich package and next install mpi4py from sources using pip.
Also, alternatively (so many alternatives, we love options), mpi4py can be installed from MacPorts <https://www.macports.org/>:
sudo port install py-mpi4py
๐จ Building from sources (the DIY era)
Okay so installing mpi4py from pre-built binary wheels, conda packages, or system packages is not always desired or appropriate. Like, for example, the mpi4py wheels published on PyPI may not be interoperable with non-mainstream, vendor-specific MPI implementations. Or a system mpi4py package may be built with an alternative, non-default MPI implementation. Awkward.
In such scenarios, mpi4py can still be installed from its source distribution (sdist) using pip:
python -m pip install --no-binary=mpi4py mpi4py
You can also install the in-development version with:
python -m pip install git+https://github.com/mpi4py/mpi4py
or:
python -m pip install https://github.com/mpi4py/mpi4py/tarball/master
Note: ๐ Installing mpi4py from its source distribution (available on PyPI) or Git source code repository (available on GitHub) requires a C compiler and a working MPI implementation with development headers and libraries. No compiler, no vibes, no mpi4py. Periodt.
Warning: ๐ญ pip keeps previously built wheel files in its cache for future reuse. So if you want to reinstall the mpi4py package from its source distribution using a different or updated MPI implementation, you have to either first remove the cached wheel file:
python -m pip cache remove mpi4py
python -m pip install --no-binary=mpi4py mpi4py
or ask pip to disable the cache:
python -m pip install --no-cache-dir --no-binary=mpi4py mpi4py
Pick your fighter. Both work. ๐ซถ
๐ง Build backends (yes, there are three)
mpi4py supports three different build backends, and honestly? iconic:
- setuptools <https://setuptools.pypa.io/> โ the default โจ
- scikit-build-core <https://scikit-build-core.readthedocs.io/> โ CMake <https://cmake.org/>-based
- meson-python <https://meson-python.readthedocs.io/> โ Meson <https://mesonbuild.com/>-based
The build backend can be selected by setting the MPI4PY_BUILD_BACKEND environment variable. That's the vibe check right there.
MPI4PY_BUILD_BACKEND
- Choices โ
"setuptools","scikit-build-core","meson-python" - Default โ
"setuptools" - Request a build backend for building mpi4py from sources.
๐ธ Using setuptools
Tip: Set theMPI4PY_BUILD_BACKENDenvironment variable to"setuptools"to use the setuptools <https://setuptools.pypa.io/> build backend.
When using the default setuptools <https://setuptools.pypa.io/> build backend, mpi4py relies on the legacy Python distutils framework to build C extension modules. Legacy, yes. Still doing the job, also yes. The following environment variables affect the build configuration โ memorize these, bestie, they're the whole plot:
MPI4PY_BUILD_MPICCโ Thempicccompiler wrapper command is searched for in the executable search path (thePATHenvironment variable) and used to compile thempi4py.MPI<#module-mpi4py.MPI> C extension module. Alternatively, use theMPI4PY_BUILD_MPICCenvironment variable to the full path or command corresponding to the MPI-aware C compiler.MPI4PY_BUILD_MPILDโ Thempicccompiler wrapper command is also used for linking thempi4py.MPI<#module-mpi4py.MPI> C extension module. Alternatively, use theMPI4PY_BUILD_MPILDenvironment variable to specify the full path or command corresponding to the MPI-aware C linker.MPI4PY_BUILD_MPICFGโ If the MPI implementation does not provide a compiler wrapper, or it is not installed in a default system location, all relevant build information like include/library locations and library lists can be provided in an ini-style configuration file under a[mpi]section. mpi4py can then be asked to use the custom build information by setting theMPI4PY_BUILD_MPICFGenvironment variable to the full path of the configuration file. As an example, see thempi.cfgfile located in the top level mpi4py source directory. ๐MPI4PY_BUILD_CONFIGUREโ Some vendor MPI implementations may not provide complete coverage of the MPI standard, or may provide partial features of newer MPI standard versions while advertising support for an older version. Setting theMPI4PY_BUILD_CONFIGUREenvironment variable to a non-empty string will trigger the run of exhaustive checks for the availability of all MPI constants, predefined handles, and routines. Thorough queen behavior.MPI4PY_BUILD_MPIABIโ Setting theMPI4PY_BUILD_MPIABIenvironment variable to"1"enables enhanced support for the MPI 5.0 standard ABI and the MPICH or Open MPI legacy ABIs. Thempi4py.MPI<#module-mpi4py.MPI> extension module is then able to dynamically link at runtime with older versions (down to the MPI 3.0 standard) of the corresponding MPI implementation used at compile time. This feature is only available on Linux, macOS, and Windows. POSIX-like systems other than Linux and macOS are not currently supported, although they could easily be: all what is needed is for the platform to either support weak symbols in shared modules/libraries, or support the standard POSIXdlopen()/dlsym()APIs.MPI4PY_BUILD_PYSABIโ Build with the CPython 3.10+ Stable ABI <https://docs.python.org/3/c-api/stable.html#stable-abi>. Setting theMPI4PY_BUILD_PYSABIenvironment variable to a string"{major}.{minor}"defines thePy_LIMITED_API<https://docs.python.org/3/c-api/stable.html#c.Py_LIMITED_API> value to use for building extension modules.
The following environment variables are aliases for the ones described above. Having shorter names, they are convenient for occasional use in the command line. Its usage is not recommended in automation scenarios like packaging recipes, deployment scripts, and container image creation. (Cute for a one-off, not for the group project, iykyk.)
MPICCโ Convenience alias forMPI4PY_BUILD_MPICC.MPILDโ Convenience alias forMPI4PY_BUILD_MPILD.MPICFGโ Convenience alias forMPI4PY_BUILD_MPICFG.
โญ Using scikit-build-core
Tip: Set theMPI4PY_BUILD_BACKENDenvironment variable to"scikit-build-core"to use the scikit-build-core <https://scikit-build-core.readthedocs.io/> build backend.
When using the scikit-build-core <https://scikit-build-core.readthedocs.io/> build backend, mpi4py delegates all of MPI build configuration to CMake <https://cmake.org/>'s FindMPI <https://cmake.org/cmake/help/latest/module/FindMPI.html> module. Besides the obvious advantage of cross-platform support, this delegation to CMake may be convenient in build environments exposing vendor software stacks via intricate module systems. ๐ฆ
Note however that mpi4py will not be able to look for MPI routines available beyond the MPI standard version the MPI implementation advertises to support (via the MPI_VERSION and MPI_SUBVERSION macro constants in the mpi.h header file), and any missing MPI constant or symbol will prevent a successful build. ๐
๐ Using meson-python
Tip: Set theMPI4PY_BUILD_BACKENDenvironment variable to"meson-python"to use the meson-python <https://meson-python.readthedocs.io/> build backend.
When using the meson-python <https://meson-python.readthedocs.io/> build backend, mpi4py delegates build tasks to the Meson <https://mesonbuild.com/> build system.
Warning: ๐จ mpi4py support for the meson-python <https://meson-python.readthedocs.io/> build backend is experimental. For the time being, users must set theCC<https://docs.python.org/3/using/configure.html#envvar-CC> environment variable to the command or path corresponding to thempiccC compiler wrapper. Don't skip this step, bestie, the build will simply not cooperate. ๐ญ
๐ธ DEVELOPMENT ๐ธ
โจ Prerequisites โจ
okay bestie, before you can develop MPI for Python you need to have the following software properly installed, no skipping:
- Python 3.8 or above. (the link in the og docs points to <https://www.python.org/> ๐)
- The Cython compiler. (<https://cython.org/>)
- A working MPI implementation like MPICH (<https://www.mpich.org/>) or Open MPI (<https://www.open-mpi.org/>), preferably supporting MPI-4 and built with shared/dynamic libraries. ๐ซถ
Optionally, consider installing the following packages:
- NumPy (<https://numpy.org/>) for enabling comprehensive testing of MPI communication.
- CuPy (<https://cupy.dev/>) for enabling comprehensive testing with a GPU-aware MPI. ๐ฅ
- Sphinx (<https://www.sphinx-doc.org/>) to build the documentation.
Tip: Most routine development tasks like building, installing in editable mode, testing, and generating documentation can be performed with the spin (<https://github.com/scientific-python/spin>) developer tool. Run spin at the top level source directory for a list of available subcommands. ๐ง
๐ ๏ธ Building ๐ ๏ธ
MPI for Python uses a setuptools-based build system that relies on the setup.py file. Some setuptools commands (e.g., build) accept additional options:
--mpi=โ Lets you pass a section with MPI configuration within a special configuration file. Alternatively, you can use theMPICFGenvironment variable.--mpicc=โ Specify the path or name of thempiccC compiler wrapper. Alternatively, use theMPICCenvironment variable.--mpild=โ Specify the full path or name for the MPI-aware C linker. Alternatively, use theMPILDenvironment variable. If not set, thempiccC compiler wrapper is used for linking.--configureโ Runs exhaustive tests for checking about missing MPI types, constants, and functions. This option should be passed in order to build MPI for Python against old MPI-1, MPI-2, or MPI-3 implementations, possibly providing a subset of MPI-4.
If you use a MPI implementation providing a mpicc C compiler wrapper (e.g., MPICH or Open MPI), it will be used for compilation and linking. This is the preferred and easiest way to build MPI for Python. ๐
If mpicc is found in the executable search path (PATH environment variable), simply run the build command:
$ python setup.py build
If mpicc is not in your search path or the compiler wrapper has a different name, you can run the build command specifying its location, either via the --mpicc command option or using the MPICC environment variable:
$ python setup.py build --mpicc=/path/to/mpicc
$ env MPICC=/path/to/mpicc python setup.py build
Alternatively, you can provide all the relevant information about your MPI implementation by editing the mpi.cfg file located in the top level source directory. You can use the default section [mpi] or add a new custom section, for example [vendor_mpi] (see the examples provided in the mpi.cfg file as a starting point to write your own section):
[mpi]
include_dirs = /usr/local/mpi/include
libraries = mpi
library_dirs = /usr/local/mpi/lib
runtime_library_dirs = /usr/local/mpi/lib
[vendor_mpi]
include_dirs = /opt/mpi/include ...
libraries = mpi ...
library_dirs = /opt/mpi/lib ...
runtime_library_dirs = /opt/mpi/lib ...
...
and then run the build command specifying you custom configuration section:
$ python setup.py build --mpi=vendor_mpi
$ env MPICFG=vendor_mpi python setup.py build
๐ฆ Installing ๐ฆ
MPI for Python can be installed in editable mode:
$ python -m pip install --editable .
After modifying Cython sources, an in-place rebuild is needed:
$ python setup.py build --inplace
๐งช Testing ๐งช
To quickly test the installation:
$ mpiexec -n 5 python -m mpi4py.bench helloworld
Hello, World! I am process 0 of 5 on localhost.
Hello, World! I am process 1 of 5 on localhost.
Hello, World! I am process 2 of 5 on localhost.
Hello, World! I am process 3 of 5 on localhost.
Hello, World! I am process 4 of 5 on localhost.
$ mpiexec -n 5 python -m mpi4py.bench ringtest -l 10 -n 1048576
time for 10 loops = 0.00361614 seconds (5 processes, 1048576 bytes)
If you installed from a git clone or the source distribution, issuing at the command line:
$ mpiexec -n 5 python demo/helloworld.py
will launch a five-process run of the Python interpreter and run the demo script demo/helloworld.py from the source distribution. slay. ๐
You can also run all the unittest scripts:
$ mpiexec -n 5 python test/main.py
or, if you have the pytest (<https://docs.pytest.org/>) unit testing framework installed:
$ mpiexec -n 5 pytest
๐ GUIDELINES ๐
๐ Fair play ๐
Summary
This section defines Rules of Play for companies and outside developers that engage with the mpi4py project. It covers:
- Restrictions on use of the mpi4py name.
- How and whether to publish a modified distribution.
- How to make us aware of patched versions.
After reading this section, companies and developers will know what kinds of behavior the mpi4py developers and contributors would like to see, and which we consider troublesome, bothersome, and unacceptable.
This document is a close adaptation of NumPy NEP 36 (<https://numpy.org/neps/nep-0036-fair-play.html>).
Motivation
Occasionally, we learn of modified mpi4py versions and binary distributions circulated by outsiders. These patched versions can cause problems to mpi4py users (see, e.g., mpi4py/mpi4py#508 โ <https://github.com/mpi4py/mpi4py/issues/508>). When issues like these arise, our developers waste time identifying the problematic release, locating alterations, and determining an appropriate course of action. ๐ญ
In addition, packages on the Python Packaging Index are sometimes named such that users assume they are sanctioned or maintained by the mpi4py developers. We wish to reduce the number of such incidents.
Scope
This document aims to define a minimal set of rules that, when followed, will be considered good-faith efforts in line with the expectations of the mpi4py developers and contributors.
Our hope is that companies and outside developers who feel they need to modify mpi4py will first consider contributing to the project, or use alternative mechanisms for patching and extending mpi4py.
When in doubt, please talk to us first (<https://github.com/mpi4py/mpi4py/discussions/>). We may suggest an alternative; at minimum, we'll be informed and we may even grant an exception if deemed appropriate. ๐ซถ
โจ Fair play rules โจ
- Do not reuse the mpi4py name for projects not affiliated with the mpi4py project.
At time of writing, there are only a handful of mpi4py-named packages developed by the mpi4py project, including mpi4py and mpi4py-fft. We ask that outside packages not include the phrase mpi4py, i.e., avoid names such as mycompany-mpi4py or mpi4py-mycompany.
To be clear, this rule only applies to modules (package names); it is perfectly acceptable to have a submodule of your own package named mycompany.mpi4py.
- Do not publish binary mpi4py wheels on PyPI (<https://pypi.org/>).
We ask companies and outside developers to not publish binary mpi4py wheels in the main Python Package Index (<https://pypi.org/>) under names such mpi4py-mpich, mpi4py-openmpi, or mpi4py-vendor_mpi.
The usual approaches to build binary Python wheels involve the embedding of dependent shared libraries. While such an approach may seem convenient and often is, in the particular case of MPI and mpi4py it is ultimately harmful to end users. Embedding the MPI shared libraries would prevent the use of external, system-provided MPI installations with hardware-specific optimizations and site-specific tweaks. ๐
The MPI 5.0 standard features an Application Binary Interface (ABI) for MPI, see [mpi-abi-paper] and [mpi-abi-issue]. Such standardization allows for any binary dependent on the MPI library to be used with multiple MPI backends. Once MPI implementations provide support for the new MPI ABI, the mpi4py project will follow and add support to the binary wheels published on PyPI. ๐
[mpi-abi-paper] : J. Hammond, L. Dalcin, E. Schnetter, M. Pรฉrache, J. B. Besnard, J. Brown, G. Brito Gadeschi, S. Byrne, J. Schuchart, and H. Zhou. MPI Application Binary Interface Standardization. EuroMPI 2023, Bristol, UK, September 2023. <https://doi.org/10.1145/3615318.3615319>
[mpi-abi-issue] : MPI Forum GitHub Issue: MPI needs a standard ABI. <https://github.com/mpi-forum/mpi-issues/issues/751>
- Do not republish modified versions of mpi4py.
Modified versions of mpi4py make it very difficult for the developers to address bug reports, since we typically do not know which parts of mpi4py have been modified.
If you have to break this rule (and we implore you not to!), then make it clear in the __version__ tag that you have modified mpi4py, e.g.:
>>> print(mpi4py.__version__)
'4.0.0+mycompany.13`
We understand that minor patches are often required to make a library work inside of a package ecosystem. This is totally acceptable, but we ask that no substantive changes are made.
- Do not extend or modify mpi4py's API.
If you absolutely have to break the previous rule, please do not add additional functions to the namespace, or modify the API of existing functions. Having additional functions exposed in distributed versions is confusing for users and developers alike. ๐
๐ LICENSE ๐
okay so before anyone panics, here's the whole legal situation, and yes it's giving โจofficialโจ but it's also very chill, don't worry ๐ซถ
Copyright (c) 2025, Lisandro Dalcin โ that's the whole copyright line, bestie, keep it sacred ๐
Here's the actual license text, verbatim, because legal stuff is the one thing you do NOT paraphrase, fr fr:
Copyright (c) 2025, Lisandro Dalcin
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS โAS
ISโ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
so what does all that actually mean in human words? let me translate ๐
- if you hand out the source code, you have to keep the copyright notice, the conditions list, and the disclaimer in there. no deleting receipts.
- if you hand out a compiled binary, same deal โ the copyright notice, conditions, and disclaimer gotta show up in the docs and/or other materials that ship with it.
- you cannot use the copyright holder's name or the contributors' names to endorse or promote stuff built from this software without asking first. no clout-leeching, periodt.
and the big all-caps bit? that's the classic "no warranties" scream ๐ฃ๏ธ โ the software comes โAS ISโ, no express or implied warranty of any kind (including merchantability or fitness for a particular purpose), and nobody's liable for any direct, indirect, incidental, special, exemplary, or consequential damages โ including procurement of substitute goods or services, loss of use, data, or profits, or business interruption โ no matter the theory of liability (contract, strict liability, or tort, including negligence or otherwise) that arises out of using this software, even if they were told it might happen. it's giving standard open-source protective energy, lowkey iconic ๐
๐ CHANGES ๐
the lore. the timeline. the glow-up history. buckle up bestie, we're going chronologically backwards ๐
Release 4.1.1 [2025-10-10]
- Add MPIABI-aware import hook support. โจ
- Support
MPI.ERR_ERRHANDLER<#mpi4py.MPI.ERR_ERRHANDLER>with Open MPI. - Fix Windows build issues with Intel MPI 2021.16. ๐ช
- Minor fixes and improvements to typing stubs.
- Minor fixes to documentation.
- Publish Python 3.8-3.14 and PyPy 3.11 wheels. ๐
- PyPy 3.10 (EOL) wheels are no longer published. rest in peace ๐
Release 4.1.0 [2025-06-25]
New features
- Publish binary wheel packages on PyPI
<https://pypi.org/project/mpi4py/#files>with support for multiple operating systems (Linux, macOS, Windows), processor architectures (AMD64, ARM64), MPI implementations (MPICH, Open MPI, and their ABI-compatible derivatives), and Python implementations (CPython, PyPy). likeโฆ the sheer coverage?? obsessed ๐ - Add support for the MPI 5.0 standard.
- MPI handle serialization with integral values.
- Fixed-size Fortran
LOGICALdatatypes. - Query ABI version/info and Fortran ABI info.
MPI.Datatype.Create_contiguous<#mpi4py.MPI.Datatype.Create_contiguous>now uses BigMPI<https://doi.org/10.1109/ExaMPI.2014.5>'s approach when using MPI implementations that do not yet support the MPI 4.0 large-count APIs.- Add support for
MPI.FLOAT16_T<#mpi4py.MPI.FLOAT16_T>andMPI.BFLOAT16_T<#mpi4py.MPI.BFLOAT16_T>datatypes. These datatypes are not yet standard but available as extensions in MPI implementations. ๐ง - Add
MPI.Status.tomemory<#mpi4py.MPI.Status.tomemory>to expose the status contents as amemoryview<https://docs.python.org/3/library/stdtypes.html#memoryview>object.
Enhancements
- Support (opt-in via
MPI4PY_BUILD_PYSABI<#envvar-MPI4PY_BUILD_PYSABI>) for building withPy_LIMITED_API<https://docs.python.org/3/c-api/stable.html#c.Py_LIMITED_API>under Python 3.10+ (requires Cython 3.1+). - Support (opt-in via
MPI4PY_BUILD_MPIABI<#envvar-MPI4PY_BUILD_MPIABI>) for building with the MPI 5.0 standard ABI and the MPICH or Open MPI legacy ABIs. TheMPI<#module-mpi4py.MPI>extension module will be able to dynamically link at runtime with older versions (down to the MPI 3.0 standard) of the MPI implementation used at compile time. Only available on Linux, macOS, and Windows. ๐ฅ - Support a
buffersizeparameter in theMPIPoolExecutor.map()<#mpi4py.futures.MPIPoolExecutor.map>andMPIPoolExecutor.starmap()<#mpi4py.futures.MPIPoolExecutor.starmap>methods to limit the number of pending tasks. - Improve ownership management of DLPack capsules.
- Reimplement MPI DLL search path on Windows.
- Minor fixes to typing stubs and documentation.
Backward-incompatible changes
โ ๏ธ heads up bestie, these will absolutely bite your old code, read carefully
- Python 3.8+ is required. ๐
- The
MPI.Exception<#mpi4py.MPI.Exception>class is now a heap type. - The types of the
MPI.BOTTOM<#mpi4py.MPI.BOTTOM>,MPI.IN_PLACE<#mpi4py.MPI.IN_PLACE>, andMPI.BUFFER_AUTOMATIC<#mpi4py.MPI.BUFFER_AUTOMATIC>are no longer subclasses ofint<https://docs.python.org/3/library/functions.html#int>. yeah. that one. ๐ญ
Release 4.0.3 [2025-02-13]
- Fix DLPack v1.0 support. ๐ฉน
Release 4.0.2 [2025-02-01]
- Support MPI-4 features within Intel MPI 2021.14.
- Various fixes and updates to tests.
- Minor fixes to typing support.
- Minor fix to documentation.
Release 4.0.1 [2024-10-11]
- Update support for Python 3.13:
- Enable Cython 3.1 support for free-threaded CPython. ๐งต
- Allow compiling Cython-generated C sources with the full Python C-API.
- Fix MPI DLL path workarounds on Windows after changes to
locals().
- Enhancements to test suite:
- Support XML reports via
unittest-xml-reporting. - Add command line options to exclude tests by patterns and files.
- Refactor Python 2 code to use Python 3 constructs using
pyupgrade.
- Support XML reports via
- Miscellaneous:
- Minor and mostly inconsequential subclass fix in
mpi4py.util.pkl5. - Update compatibility workarounds for legacy MPICH 3.0 release.
- Minor and mostly inconsequential subclass fix in
Release 4.0.0 [2024-07-28]
New features
- Add support for the MPI-4.0 standard.
- Use large count MPI-4 routines.
- Add persistent collective communication.
- Add partitioned point-to-point communication.
- Add new communicator constructors.
- Add the
Sessionclass and its methods.
- Add support for the MPI-4.1 standard.
- Add non-destructive completion test for multiple requests.
- Add value-index datatype constructor.
- Add communicator/session buffer attach/detach/flush.
- Support for removal of error classes/codes/strings.
- Support for querying hardware resource information.
- Add preliminary support for the upcoming MPI-5.0 standard.
- User-level failure mitigation (ULFM). ๐โก๏ธโจ
mpi4py.util.pool: New drop-in replacement formultiprocessing.pool.mpi4py.util.sync: New synchronization utilities.- Add runtime check for mismatch between
mpiexecand MPI library. ๐ต๏ธ - Support
scikit-build-core<https://scikit-build.readthedocs.io/>as an alternative build backend. - Support
meson-python<https://meson-python.readthedocs.io/>as an alternative build backend.
Enhancements
mpi4py.futures: Support for parallel tasks.mpi4py.futures: Report exception tracebacks in workers.mpi4py.util.pkl5: Add support for collective communication.- Add methods
Datatype.fromcode(),Datatype.tocode()and attributesDatatype.typestr,Datatype.typecharto simplify NumPy interoperability for simple cases. - Add methods
Comm.Create_errhandler(),Win.Create_errhandler(), andFile.Create_errhandler()to create custom error handlers. - Add support for pickle serialization of instances of MPI types. All instances of
Datatype,Info, andStatuscan be serialized. Instances ofOpcan be serialized only if created through mpi4py by callingOp.Create(). Instances of other MPI types can be serialized only if they reference predefined handles. - Add
handleattribute andfromhandle()class method to MPI classes to ease interoperability with external code. Thehandlevalue is an unsigned integer guaranteed to fit on the platform'suintptr_tC type. - Add lowercase
free()method to MPI classes to ease MPI object deallocation and cleanup. This method eventually attempts to callFree(), but only if the object's MPI handle is not a null or predefined handle, and such call is allowed within the World Model init/finalize. ๐งน
Backward-incompatible changes
โ ๏ธ this is the big one, the era shift, the before-and-after
- Python 2 is no longer supported, Python 3.6+ is required, but typing stubs are supported for Python 3.8+. ๐ bye python 2
- The
Intracomm.Create_group()method is no longer defined in the baseCommclass. Group.Compare()andComm.Compare()are no longer class methods but instance methods. Existing codes using the former class methods are expected to continue working.Group.Translate_ranks()is no longer a class method but an instance method. Existing codes using the former class method are expected to continue working.- The
LBandUBdatatypes are no longer available, useDatatype.Create_resized()instead. - The
HOSTpredefined attribute key is no longer available. - The
MPI.memoryclass has been renamed toMPI.buffer. The old name is still available as an alias to the new name. ๐ - The
mpi4py.dlmodule is no longer available. - The
mpi4py.get_configfunction returns an empty dictionary.
Miscellaneous
- The project is now licensed under the BSD-3-Clause license. This change is fairly inconsequential for users and distributors. It simply adds an additional clause against using contributor names for promotional purposes without their consent.
- Add a new guidelines section to documentation laying out new fair play rules. These rules ask companies and outside developers to refrain from reusing the mpi4py name in unaffiliated projects, publishing binary mpi4py wheels on the main Python Package Index (PyPI), and distributing modified versions with incompatible or extended API changes. The primary motivation of these rules is to avoid fragmentation and end-user confusion. ๐ซถ
Release 3.1.6 [2024-04-14]
โ ๏ธ This is the last release supporting Python 2.
- Fix various build issues. ๐ง
Release 3.1.5 [2023-10-04]
โ ๏ธ This is the last release supporting Python 2.
- Rebuild C sources with Cython 0.29.36 to support Python 3.12.
Release 3.1.4 [2022-11-02]
โ ๏ธ This is the last release supporting Python 2.
- Rebuild C sources with Cython 0.29.32 to support Python 3.11.
- Fix contiguity check for DLPack and CAI buffers.
- Workaround build failures with setuptools v60.
Release 3.1.3 [2021-11-25]
โ ๏ธ This is the last release supporting Python 2.
- Add missing support for
MPI.BOTTOMto generalized all-to-all collectives.
Release 3.1.2 [2021-11-04]
โ ๏ธ This is the last release supporting Python 2.
mpi4py.futures: add a_max_workersproperty toMPIPoolExecutor. yes bestie, you can finally peek at it ๐mpi4py.util.dtlib: fix the computation of alignment for predefined datatypes.mpi4py.util.pkl5: fix a deadlock when usingssend()+mprobe(). (not the fun kind of deadlock, there is no fun kind of deadlock ๐ญ)mpi4py.util.pkl5: add environment variableMPI4PY_PICKLE_THRESHOLD.mpi4py.rc: interpret"y"and"n"strings as boolean values. slay, lowercase rights ๐ซถ- Fix/add typemap/typestr for
MPI.WCHAR/MPI.COUNTdatatypes. - Minor fixes and additions to documentation.
- Minor fixes to typing support.
- Support for local version identifier (PEP-440).
๐ Release 3.1.1 [2021-08-14]
Warning: This is the last release supporting Python 2. ๐ซก pour one out
- Fix typo in
Requires-Pythonpackage metadata. - Regenerate C sources with Cython 0.29.24.
๐ธ Release 3.1.0 [2021-08-12]
Warning: This is the last release supporting Python 2. (yes, again, it's giving final-season energy ๐)
- New features:
mpi4py.util: a whole new package collecting miscellaneous utilities. it's giving โจutility drawerโจ
- Enhancements:
- Add pickle-based
Request.waitsome()andRequest.testsome(). - Add lowercase methods
Request.get_status()andRequest.cancel(). - Support for passing Python GPU arrays compliant with the DLPack <https://github.com/dmlc/dlpack> data interchange mechanism (link <https://data-apis.org/array-api/latest/design_topics/data_interchange.html>) and the
__cuda_array_interface__(CAI) standard (link <https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html>) to uppercase methods. This support requires that mpi4py is built against CUDA-aware MPI <https://developer.nvidia.com/blog/introduction-cuda-aware-mpi/> implementations. This feature is currently experimental and subject to future changes. โ ๏ธ experimental means experimental, bestie, don't build your whole thesis on it mpi4py.futures: add support for initializers and canceling futures at shutdown. Environment variables names now follow the patternMPI4PY_FUTURES_*, the previousMPI4PY_*names are deprecated. (deprecated = still works, still judging you ๐ )- Add type annotations to Cython code. The first line of the docstring of functions and methods displays a signature including type annotations.
- Add companion stub files to support type checkers. your IDE is gonna be so normal about this fr fr
- Support for weak references.
- Add pickle-based
- Miscellaneous:
- Add a new mpi4py publication (link <https://doi.org/10.1109/MCSE.2021.3083216>) to the citation listing. cite your sources, academic girlies ๐
๐ฆ Release 3.0.3 [2019-11-04]
- Regenerate Cython wrappers to support Python 3.8.
โญ Release 3.0.2 [2019-06-11]
- Bug fixes:
- Fix handling of readonly buffers in support for Python 2 legacy buffer interface. The issue triggers only when using a buffer-like object that is readonly and does not export the new Python 3 buffer interface.
- Fix build issues with Open MPI 4.0.x series related to removal of many MPI-1 symbols deprecated in MPI-2 and removed in MPI-3.
- Minor documentation fixes.
๐ Release 3.0.1 [2019-02-15]
- Bug fixes:
- Fix
Comm.scatter()and other collectives corrupting input send list. Add safety measures to prevent related issues in global reduction operations. (your input list said not today ๐) - Fix error-checking code for counts in
Op.Reduce_local().
- Fix
- Enhancements:
- Map size-specific Python/NumPy typecodes to MPI datatypes.
- Allow partial specification of target list/tuple arguments in the various
WinRMA methods. - Workaround for removal of
MPI_{LB|UB}in Open MPI 4.0. - Support for Microsoft MPI v10.0.
๐ Release 3.0.0 [2017-11-08]
- New features:
mpi4py.futures: execute computations asynchronously using a pool of MPI processes. This package is based onconcurrent.futuresfrom the Python standard library.mpi4py.run: run Python code and abort execution in case of unhandled exceptions to prevent deadlocks.mpi4py.bench: run basic MPI benchmarks and tests.
- Enhancements:
- Lowercase, pickle-based collective communication calls are now thread-safe through the use of fine-grained locking. ๐
- The
MPImodule now exposes amemorytype which is a lightweight variant of the builtinmemoryviewtype, but exposes both the legacy Python 2 and the modern Python 3 buffer interface under a Python 2 runtime. - The
MPI.Comm.Alltoallw()method now usescount=1anddispl=0as defaults, assuming that messages are specified through user-defined datatypes. - The
Request.Wait[all]()methods now returnTrueto match the interface ofRequest.Test[all](). - The
Winclass now implements the Python buffer interface.
- Backward-incompatible changes:
- The
bufargument of theMPI.Comm.recv()method is deprecated, passing anything butNoneemits a warning. - The
MPI.Win.memoryproperty was removed, use theMPI.Win.tomemory()method instead. - Executing
python -m mpi4pyin the command line is now equivalent topython -m mpi4py.run. For the former behavior, usepython -m mpi4py.bench. - Python 2.6 and 3.2 are no longer supported. The
mpi4py.MPImodule may still build and partially work, but other pure-Python modules under thempi4pynamespace will not. - Windows: remove support for legacy MPICH2, Open MPI, and DeinoMPI.
- The
๐ง Release 2.0.0 [2015-10-18]
- Support for MPI-3 features.
- Matched probes and receives.
- Nonblocking collectives.
- Neighborhood collectives.
- New communicator constructors.
- Request-based RMA operations.
- New RMA communication and synchronisation calls.
- New window constructors.
- New datatype constructor.
- New C++ boolean and floating complex datatypes.
- Support for MPI-2 features not included in previous releases.
- Generalized All-to-All collective (
Comm.Alltoallw()) - User-defined data representations (
Register_datarep())
- Generalized All-to-All collective (
- New scalable implementation of reduction operations for Python objects. This code is based on binomial tree algorithms using point-to-point communication and duplicated communicator contexts. To disable this feature, use
mpi4py.rc.fast_reduce = False. - Backward-incompatible changes:
- Python 2.4, 2.5, 3.0 and 3.1 are no longer supported.
- Default MPI error handling policies are overridden. After import, mpi4py sets the
ERRORS_RETURNerror handler inCOMM_SELFandCOMM_WORLD, as well as any newComm,Win, orFileinstance created through mpi4py, thus effectively ignoring the MPI rules about error handler inheritance. This way, MPI errors translate to Python exceptions. To disable this behavior and use the standard MPI error handling rules, usempi4py.rc.errors = 'default'. - Change signature of all send methods,
destis a required argument. - Change signature of all receive and probe methods,
sourcedefaults toANY_SOURCE,tagdefaults toANY_TAG. - Change signature of send lowercase-spelling methods,
objarguments are not mandatory. - Change signature of recv lowercase-spelling methods, renamed 'obj' arguments to 'buf'.
- Change
Request.Waitsome()andRequest.Testsome()to returnNoneorlist. - Change signature of all lowercase-spelling collectives,
sendobjarguments are now mandatory,recvobjarguments were removed. - Reduction operations
MAXLOCandMINLOCare no longer special-cased in lowercase-spelling methodsComm.[all]reduce()andComm.[ex]scan(), the input object must be specified as a tuple(obj, location). - Change signature of name publishing functions. The new signatures are
Publish_name(service_name, port_name, info=INFO_NULL)andUnpublish_name(service_name, port_name, info=INFO_NULL). Wininstances now cache Python objects exposing memory by keeping references instead of using MPI attribute caching.- Change signature of
Win.Lock(). The new signature isWin.Lock(rank, lock_type=LOCK_EXCLUSIVE, assertion=0). - Move
Cartcomm.Map()toIntracomm.Cart_map(). - Move
Graphcomm.Map()toIntracomm.Graph_map(). - Remove the
mpi4py.MPEmodule. - Rename the Cython definition file for use with
cimportstatement frommpi_c.pxdtolibmpi.pxd.
๐ Release 1.3.1 [2013-08-07]
- Regenerate C wrappers with Cython 0.19.1 to support Python 3.3.
- Install
*.pxdfiles in<site-packages>/mpi4pyto ease the support for Cython'scimportstatement in code requiring to access mpi4py internals. - As a side-effect of using Cython 0.19.1, ancient Python 2.3 is no longer supported. If you really need it, you can install an older Cython and run
python setup.py build_src --force.
๐ Release 1.3 [2012-01-20]
- Now
Comm.recv()accept a buffer to receive the message. - Add
Comm.irecv()andRequest.{wait|test}[any|all](). - Add
Intracomm.Spawn_multiple(). - Better buffer handling for PEP 3118 and legacy buffer interfaces.
- Add support for attribute attribute caching on communicators, datatypes and windows.
- Install MPI-enabled Python interpreter as
<path>/mpi4py/bin/python-mpi. - Windows: support for building with Open MPI.
๐ Release 1.2.2 [2010-09-13]
- Add
mpi4py.get_config()to retrieve information (compiler wrappers, includes, libraries, etc) about the MPI implementation employed to build mpi4py. - Workaround Python libraries with missing
GILState-related API calls in case of non-threaded Python builds. - Windows: look for MPICH2, DeinoMPI, Microsoft HPC Pack at their default install locations under
%ProgramFiles. - MPE: fix hacks related to old API's, these hacks are broken when MPE is built with a MPI implementations other than MPICH2.
- HP-MPI: fix for missing Fortran datatypes, use
dlopen()to load the MPI shared library beforeMPI_Init() - Many distutils-related fixes, cleanup, and enhancements, better logics to find MPI compiler wrappers.
- Support for
pip install mpi4py.
๐ซถ Release 1.2.1 [2010-02-26]
- Fix declaration in Cython include file. This declaration, while valid for Cython, broke the simple-minded parsing used in
conf/mpidistutils.pyto implement configure-tests for availability of MPI symbols. - Update SWIG support and make it compatible with Python 3. Also generate an warning for SWIG < 1.3.28.
- Fix distutils-related issues in Mac OS X. Now
ARCHFLAGSenvironment variable is honored of all Python'sconfig/Makefilevariables. - Fix issues with Open MPI < 1.4.2 related to error checking and
MPI_XXX_NULLhandles.
Release 1.2 [2009-12-29] ๐
- Automatic MPI datatype discovery for NumPy arrays and PEP-3118 buffers. So now buffer-like objects can be messaged directly โ you don't have to spell out a 2/3-list/tuple like
[data, MPI.DOUBLE]or[data, count, MPI.DOUBLE]anymore. Only basic types get this treatment tho: all C/C99-native signed/unsigned integral types, plus single/double precision real/complex floating types. Massive thanks to Eilif Muller for the initial feedback ๐ - Nonblocking send of pickled Python objects. Huge thanks to Andreas Kloeckner for the initial patch and the genuinely enlightening discussion about this glow-up ๐
Requestinstances now hold a reference to the Python object exposing the buffer involved in point-to-point communication or parallel I/O. Again, ty Andreas Kloeckner for the initial feedback โจ- Support for logging of user-defined states and events using MPE <https://www.mcs.anl.gov/research/projects/perfvis/>. Runtime (like, without requiring a recompile!) activation of logging of all MPI calls is supported on POSIX platforms implementing
dlopen(). Obsessed ๐ซถ - Support for all the new features in MPI-2.2: new C99 and F90 datatypes, distributed graph topology, local reduction operation, and other minor enhancements. Periodt ๐
- Fix for the annoying issues related to Open MPI and Python dynamic loading of extension modules on platforms supporting
dlopen(). finally ๐ญ - Fix for SLURM dynamic loading issues on SiCortex. Many thanks to Ian Langmore for providing me shell access ๐
Release 1.1.0 [2009-06-06] ๐ฆ
- Fix bug in
Comm.Iprobe()that caused segfaults, because Python C-API calls were being issued with the GIL released (issue #2). not the segfault bestie ๐ - Add
Comm.bsend()andComm.ssend()for buffered and synchronous send semantics when communicating general Python objects. - Now the call
Info.Get(key)returns a single value (like, instead of a 2-tuple). That value isNoneifkeyis not in theInfoobject, or a string otherwise. Previously the call redundantly returned(None, False)for missing key-value pairs โNoneis enough to signal a missing entry, we don't need the extra drama. - Add support for parametrized Fortran datatypes โจ
- Add support for decoding user-defined datatypes.
- Add support for user-defined reduction operations on memory buffers. However, at most 16 user-defined reduction operations can be created. Ask the author for more room if you need it ๐
Release 1.0.0 [2009-03-20] ๐
This is the first release of the all-new, Cython-based implementation of MPI for Python. Unfortunately, this implementation is not backward-compatible with the previous one ๐ญ. The list below summarizes the more important changes that can impact user codes.
- Some communication calls had overloaded functionality. Now there's a clear distinction between communication of general Python objects with pickle, and (fast, near C-speed) communication of buffer-like objects (e.g., NumPy arrays).
- for communicating general Python objects, you have to use all-lowercase methods, like
send(),recv(),bcast(), etc. - for communicating array data, you have to use
Send(),Recv(),Bcast(), etc. methods. Buffer arguments to these calls must be explicitly specified by using a 2/3-list/tuple like[data, MPI.DOUBLE], or[data, count, MPI.DOUBLE](the former one uses the byte-size ofdataand the extent of the MPI datatype to define the count).
- for communicating general Python objects, you have to use all-lowercase methods, like
- Indexing a communicator with an integer returned a special object associating the communication with a target rank, alleviating you from specifying source/destination/root arguments in point-to-point and collective communications. This functionality is no longer available, so expressions like:
MPI.COMM_WORLD[0].Send(...)
MPI.COMM_WORLD[0].Recv(...)
MPI.COMM_WORLD[0].Bcast(...)
have to be replaced by:
MPI.COMM_WORLD.Send(..., dest=0)
MPI.COMM_WORLD.Recv(..., source=0)
MPI.COMM_WORLD.Bcast(..., root=0)
- Automatic MPI initialization (i.e., at import time) requests the maximum level of MPI thread support (i.e., it is done by calling
MPI_Init_thread()and passingMPI_THREAD_MULTIPLE). In case you need to change this behavior, you can tweak the contents of thempi4py.rcmodule. - In order to obtain the values of predefined attributes attached to the world communicator, now you have to use the
Get_attr()method on theMPI.COMM_WORLDinstance:
tag_ub = MPI.COMM_WORLD.Get_attr(MPI.TAG_UB)
- In the previous implementation,
MPI.COMM_WORLDandMPI.COMM_SELFwere associated to duplicates of the (C-level)MPI_COMM_WORLDandMPI_COMM_SELFpredefined communicator handles. Now this is no longer the case โMPI.COMM_WORLDandMPI.COMM_SELFproxy the actualMPI_COMM_WORLDandMPI_COMM_SELFhandles. glow-up fr fr โจ - Convenience aliases
MPI.WORLDandMPI.SELFwere removed. Use insteadMPI.COMM_WORLDandMPI.COMM_SELF. - Convenience constants
MPI.WORLD_SIZEandMPI.WORLD_RANKwere removed. Use insteadMPI.COMM_WORLD.Get_size()andMPI.COMM_WORLD.Get_rank().
Author ๐
Lisandro Dalcin
Copyright ๐
2026, Lisandro Dalcin
and that's a wrap on the whole page bestie!! ๐ this was Release 4.1, dated March 20, 2026 โ that's the version and date stamped at the bottom of the manual page (MPI4PY(3)), and yes I'm putting it in the sign-off instead of copying the footer line, because we're cute like that ๐
๐ธ go forth and parallelize, you absolute icon ๐ซถโจ
๐ฆ where this page comes from
- ubuntu resolute: python-mpi4py-doc 4.1.1-1ubuntu2 ยท BSD-3
- ubuntu stonking: python-mpi4py-doc 4.1.1-1ubuntu2 ยท BSD-3
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms