2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2020, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
43 #include "gmxapi/context.h"
44 #include "gmxapi/exceptions.h"
46 #include "gmxapi/mpi/multiprocessingresources.h"
49 * \brief Provide details of any MPI implementation used when building the library.
51 * If the gmxapi library was built with MPI-enabled GROMACS, client software
52 * using a compatible MPI implementation may use this header to access additional
55 * Client software should use the CMake infrastructure to ensure a compatible
58 * Use of an incompatible MPI implementation will produce linking errors.
60 * \todo With resolution of #3672, we can include additional checks.
68 * \brief Convey resources assigned by the client to the new library Context.
70 * Only enabled if the required MPI library calls are available.
72 template<typename CommT, decltype(MPI_Comm_rank(CommT(), nullptr)) = 0, decltype(MPI_Comm_size(CommT(), nullptr)) = 0>
73 class ResourceAssignmentImpl : public ResourceAssignment
76 ~ResourceAssignmentImpl() override = default;
79 * \brief Initialize from borrowed communicator.
81 * \param communicator Client-provided communicator relayed through assignResource()
83 * Create an abstract wrapper for client-provided values with which to initialize
84 * simulation resources. When this wrapper is used, the client is responsible for providing
85 * a valid communicator that will remain valid for the life of the consumer.
87 explicit ResourceAssignmentImpl(const CommT& communicator) : communicator_{ communicator }
89 if (communicator_ == MPI_COMM_NULL)
91 throw UsageError("Null communicator cannot be lent.");
94 MPI_Initialized(&flag);
97 throw UsageError("Client has not initialized MPI context.");
101 [[nodiscard]] int size() const override
103 assert(communicator_ != MPI_COMM_NULL && "Resource invariant implies a valid communicator.");
105 MPI_Comm_size(communicator_, &size);
109 [[nodiscard]] int rank() const override
111 assert(communicator_ != MPI_COMM_NULL && "Resource invariant implies a valid communicator.");
112 // This default value will never be read, but the compiler can't tell
113 // that it is initialized by the MPI call.
115 MPI_Comm_rank(communicator_, &rank);
119 void applyCommunicator(CommHandle* dst) const override
121 assert(communicator_ != MPI_COMM_NULL && "Resource invariant implies a valid communicator.");
122 offerComm(communicator_, dst);
129 * \brief Template header utility for connecting to MPI implementations.
131 * To use this helper function, the client software build environment must be
132 * configured for an MPI implementation compatible with the target GROMACS library.
134 * If the library and client software are built with compatible MPI implementations,
135 * the template will capture the communicator in an opaque container that can be
136 * passed to the ContextImpl creation function. Otherwise, the opaque container
137 * will carry a suitable NULL object. The template definition is necessarily
138 * provided by a generated template header, since the definition depends on the
139 * GROMACS installation.
141 * \tparam CommT Deduced type of client-provided communicator.
142 * \param communicator MPI (sub)communicator linking collaborating processes in the new Context.
143 * \return Opaque resource handle usable when setting up execution context.
145 * \see createContext(std::unique_ptr<ResourceAssignment> resources)
147 * The client provides a communicator for work executed within the scope of the Context.
148 * Client remains responsible for freeing the communicator and finalizing the MPI environment.
150 * The communicator resource type is a template parameter because MPI_Comm is commonly a C
151 * typedef that varies between implementations, so we do not want to couple our
152 * API to it, but we cannot forward-declare it.
154 * See also https://gitlab.com/gromacs/gromacs/-/issues/3650
156 template<typename CommT>
157 std::unique_ptr<ResourceAssignment> assignResource(CommT communicator)
159 if (communicator == MPI_COMM_NULL)
161 throw UsageError("Cannot assign a Null communicator.");
163 return std::make_unique<ResourceAssignmentImpl<CommT>>(communicator);
166 // Also ref https://stackoverflow.com/questions/49259704/pybind11-possible-to-use-mpi4py
168 } // end namespace gmxapi
170 #endif // GMXAPI_MPI_H