31 XMLTag::Occurrence occ = XMLTag::OCCUR_ARBITRARY;
33 XMLTag tag(*
this,
"sockets", occ,
TAG);
34 doc =
"Communication via Sockets.";
35 tag.setDocumentation(doc);
37 auto attrPort = makeXMLAttribute(
"port", 0)
39 "Port number (16-bit unsigned integer) to be used for socket "
40 "communication. The default is \"0\", what means that the OS will "
41 "dynamically search for a free port (if at least one exists) and "
42 "bind it automatically.");
43 tag.addAttribute(attrPort);
47 "Interface name to be used for socket communication. "
48 "Default is the canonical name of the loopback interface of your platform. "
49 "Might be different on supercomputing systems, e.g. \"ib0\" "
50 "for the InfiniBand on SuperMUC. ");
51 tag.addAttribute(attrNetwork);
55 "Directory where connection information is exchanged. By default, the "
56 "directory of startup is chosen, and both solvers have to be started "
57 "in the same directory.");
58 tag.addAttribute(attrExchangeDirectory);
62 XMLTag tag(*
this,
"mpi-multiple-ports", occ,
TAG);
63 doc =
"Communication via MPI with startup in separated communication spaces, using multiple communicators.";
64 tag.setDocumentation(doc);
68 "Directory where connection information is exchanged. By default, the "
69 "directory of startup is chosen, and both solvers have to be started "
70 "in the same directory.");
71 tag.addAttribute(attrExchangeDirectory);
75 XMLTag tag(*
this,
"mpi", occ,
TAG);
76 doc =
"Communication via MPI with startup in separated communication spaces, using a single communicator";
77 tag.setDocumentation(doc);
81 "Directory where connection information is exchanged. By default, the "
82 "directory of startup is chosen, and both solvers have to be started "
83 "in the same directory.");
84 tag.addAttribute(attrExchangeDirectory);
89 attrEnforce.setDocumentation(
"Enforce the distributed communication to a gather-scatter scheme. "
90 "Only recommended for trouble shooting.");
93 attrTwoLevel.setDocumentation(
"Use a two-level initialization scheme. "
94 "Recommended for large parallel runs (>5000 MPI ranks).");
96 auto attrFrom = XMLAttribute<std::string>(
"acceptor")
98 "First participant name involved in communication. For performance reasons, we recommend to use "
99 "the participant with less ranks at the coupling interface as \"acceptor\" in the m2n communication.");
100 auto attrTo = XMLAttribute<std::string>(
"connector")
101 .setDocumentation(
"Second participant name involved in communication.");
103 for (XMLTag &tag : tags) {
104 tag.addAttribute(attrFrom);
105 tag.addAttribute(attrTo);
106 tag.addAttribute(attrEnforce);
107 tag.addAttribute(attrTwoLevel);
115 if ((conf.acceptor == acceptor && conf.connector == connector) ||
116 (conf.connector == acceptor && conf.acceptor == connector)) {
120 PRECICE_ERROR(
"There is no m2n communication configured between participants \"" + acceptor +
"\" and \"" + connector +
"\". Please add an appropriate \"<m2n />\" tag.");
126 [acceptor, connector](
const auto &conf) {
127 return (conf.acceptor == acceptor && conf.connector == connector) || (conf.connector == acceptor && conf.acceptor == connector);
140 if (enforceGatherScatter && useTwoLevelInit) {
143 if (context.
size == 1 && useTwoLevelInit) {
144 throw std::runtime_error{
"To use two-level initialization, both participants need to run in parallel. If you want to run in serial please switch two-level initialization off."};
150 if (tagName ==
"sockets") {
155 "The value given for the \"port\" attribute is not a 16-bit unsigned integer: {}", port);
158 comFactory = std::make_shared<com::SocketCommunicationFactory>(port,
false, network, dir);
159 com = comFactory->newCommunication();
160 }
else if (tagName ==
"mpi-multiple-ports") {
163 PRECICE_ERROR(
"Communication type \"mpi-multiple-ports\" can only be used if preCICE was compiled with MPI support enabled. "
164 "Either switch to a \"sockets\" communication or recompile preCICE with \"PRECICE_MPICommunication=ON\".");
166#ifdef OMPI_MAJOR_VERSION
167 PRECICE_WARN(
"preCICE was compiled with OpenMPI and configured to use <m2n:mpi-multiple-ports />, which can cause issues in connection build-up. Consider switching to sockets if you encounter problems. Ignore this warning if participants find each other and the simulation starts.");
169 comFactory = std::make_shared<com::MPIPortsCommunicationFactory>(dir);
170 com = comFactory->newCommunication();
172 }
else if (tagName ==
"mpi") {
175 PRECICE_ERROR(
"Communication type \"{}\" can only be used if preCICE was compiled with MPI support enabled. "
176 "Either switch to a \"sockets\" communication or recompile preCICE with \"PRECICE_MPICommunication=ON\".",
179#ifdef OMPI_MAJOR_VERSION
180 PRECICE_WARN(
"preCICE was compiled with OpenMPI and configured to use <m2n:{} />, which can cause issues in connection build-up. Consider switching to sockets if you encounter problems. Ignore this warning if participants find each other and the simulation starts.", tagName);
182 comFactory = std::make_shared<com::MPISinglePortsCommunicationFactory>(dir);
183 com = comFactory->newCommunication();
190 if (enforceGatherScatter) {
191 distrFactory = std::make_shared<GatherScatterComFactory>(com);
193 distrFactory = std::make_shared<PointToPointComFactory>(comFactory);
198 std::make_shared<m2n::M2N>(com, distrFactory,
false, useTwoLevelInit),
209 bool alreadyAdded =
false;
211 alreadyAdded |= conf.acceptor == acceptor && conf.connector == connector;
212 alreadyAdded |= conf.connector == acceptor && conf.acceptor == connector;
214 PRECICE_CHECK(!alreadyAdded,
"Multiple m2n communications between participant \"" + acceptor +
"\" and \"" + connector +
"\" are not allowed. Please remove redundant <m2n /> tags between them.");
#define PRECICE_ERROR(...)
#define PRECICE_WARN(...)
#define PRECICE_CHECK(check,...)
#define PRECICE_ASSERT(...)
const std::string ATTR_EXCHANGE_DIRECTORY
bool isM2NConfigured(const std::string &acceptor, const std::string &connector)
std::vector< ConfiguredM2N > _m2ns
const std::string ATTR_USE_TWO_LEVEL_INIT
m2n::PtrM2N getM2N(const std::string &acceptor, const std::string &connector)
Returns the communication object for the given user names.
virtual void xmlTagCallback(const xml::ConfigurationContext &context, xml::XMLTag &callingTag)
Callback at begin of XML tag.
M2NConfiguration(xml::XMLTag &parent)
void checkDuplicates(const std::string &acceptor, const std::string &connector)
const std::string ATTR_ENFORCE_GATHER_SCATTER
XMLAttribute & setDocumentation(std::string documentation)
Sets a documentation string for the attribute.
Represents an XML tag to be configured automatically.
const std::string & getNamespace() const
Returns xml namespace.
std::string getStringAttributeValue(const std::string &name, std::optional< std::string > default_value=std::nullopt) const
bool getBooleanAttributeValue(const std::string &name, std::optional< bool > default_value=std::nullopt) const
const std::string & getName() const
Returns name (without namespace).
int getIntAttributeValue(const std::string &name, std::optional< int > default_value=std::nullopt) const
XMLTag & addSubtag(const XMLTag &tag)
Adds an XML tag as subtag by making a copy of the given tag.
contains the logic of the parallel communication between participants.
std::string loopbackInterfaceName()
Returns the name of the canonical loopback interface on this system.
Tightly coupled to the parameters of Participant()