This project is a proposal and a prototype implementation of a non-blocking message passing interface. Its three main goals are:
- fast and correct programs should be easy to write,
- the user should remain in full control,
- fail hard and early, but allow recovery if desired.
This goals motivate the following design decisions:
- non-blocking only interface (those who want to block can do so explicitly),
- (insanely) strongly-typed,
- generic (via concepts, polymorphic function objects, and tag-dispatching),
- extensible (via non-member non-friend functions and ADL),
- template meta-programming for zero abstraction penalty,
- strong debug mode (with assertions that do not increase the algorithmic complexity)
- insanely strong debug mode (with assertions that do increase the algorithmic complexity)
- customizable error handling: exception vs hard failure
- no external dependencies (except for the C++ standard library and
<mpi.h>
)
And the following implementation details about asynchronous message passing:
-
non-blocking API:
- callback-based: offer a maximum performance call-back based asynchronous API following Boost.ASIO in the spirit of N4045: Library Foundations for Asynchronous Operations.
- future-based: offer an easy to use albeit potentially slightly slower continuation
based interface via
<futures>
. To minimize the impact on performance:- allow the user to customize the future type, and
- provide stack allocated futures.
-
executors: the users should be able to choose the executor of the library as well as provide their own. Considering N4046 - Executors and Asynchronous Operations and the conflict between the run-time polymorphic nature of Google's proposal N3785 - Executors and schedulers, revision 3 and the goals of this library (performance and correctness) the executors that this library will target will be concept based.
-
serialization:
- serialization of array-like data-structures (
<vector>
,<stack>
,<queue>
,Eigen3::VectorXD
) of trivial ypes with standard layout should be as efficient as serializing a C pointer to a literal type with a size. This is already very hard since in C++, e.g., a vector does not manage/own its memory (its allocator does) so avoiding extra allocations when using these is hard. - serialization of complex data-structures typically introduces a performance penalty since buffers have to be allocated. This performance penalty should not be abstracted away. The users should remain in control here and manage the life-time of these buffers themselves. Utilities should be provided to ease the management of these buffers.
- serialization of array-like data-structures (