.. Copyright (c) 2019 The STE||AR-Group SPDX-License-Identifier: BSL-1.0 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) .. _modules_mpi: ========= async_mpi ========= The MPI library is intended to simplify the process of integrating |mpi|_ based codes with the |hpx| runtime. Any MPI function that is asynchronous and uses an ``MPI_Request`` may be converted into an ``hpx::future``. The syntax is designed to allow a simple replacement of the MPI call with a futurized async version that accepts an executor instead of a communicator, and returns a future instead of assigning a request. Typically, an MPI call of the form .. code-block:: c++ int MPI_Isend(buf, count, datatype, rank, tag, comm, request); becomes .. code-block:: c++ hpx::future f = hpx::async(executor, MPI_Isend, buf, count, datatype, rank, tag); When the MPI operation is complete, the future will become ready. This allows communication to integrated cleanly with the rest of |hpx|, in particular the continuation style of programming may be used to build up more complex code. Consider the following example, that chains user processing, sends and receives using continuations... .. code-block:: c++ // create an executor for MPI dispatch hpx::mpi::experimental::executor exec(MPI_COMM_WORLD); // post an asynchronous receive using MPI_Irecv hpx::future f_recv = hpx::async( exec, MPI_Irecv, &data, rank, MPI_INT, rank_from, i); // attach a continuation to run when the recv completes, f_recv.then([=, &tokens, &counter](auto&&) { // call an application specific function msg_recv(rank, size, rank_to, rank_from, tokens[i], i); // send a new message hpx::future f_send = hpx::async( exec, MPI_Isend, &tokens[i], 1, MPI_INT, rank_to, i); // when that send completes f_send.then([=, &tokens, &counter](auto&&) { // call an application specific function msg_send(rank, size, rank_to, rank_from, tokens[i], i); }); } The example above makes use of ``MPI_Isend`` and ``MPI_Irecv``, but *any* MPI function that uses requests may be futurized in this manner. The following is a (non exhaustive) list of MPI functions that *should* be supported, though not all have been tested at the time of writing (please report any problems to the issue tracker). .. code-block:: c++ int MPI_Isend(...); int MPI_Ibsend(...); int MPI_Issend(...); int MPI_Irsend(...); int MPI_Irecv(...); int MPI_Imrecv(...); int MPI_Ibarrier(...); int MPI_Ibcast(...); int MPI_Igather(...); int MPI_Igatherv(...); int MPI_Iscatter(...); int MPI_Iscatterv(...); int MPI_Iallgather(...); int MPI_Iallgatherv(...); int MPI_Ialltoall(...); int MPI_Ialltoallv(...); int MPI_Ialltoallw(...); int MPI_Ireduce(...); int MPI_Iallreduce(...); int MPI_Ireduce_scatter(...); int MPI_Ireduce_scatter_block(...); int MPI_Iscan(...); int MPI_Iexscan(...); int MPI_Ineighbor_allgather(...); int MPI_Ineighbor_allgatherv(...); int MPI_Ineighbor_alltoall(...); int MPI_Ineighbor_alltoallv(...); int MPI_Ineighbor_alltoallw(...); Note that the |hpx| mpi futurization wrapper should work with *any* asynchronous ``MPI`` call, as long as the function signature has the last two arguments ``MPI_xxx(..., MPI_Comm comm, MPI_Request *request)`` - internally these two parameters will be substituted by the executor and future data parameters that are supplied by template instantiations inside the ``hpx::mpi`` code. See the :ref:`API reference ` of this module for more details.