У меня есть ситуация, когда все процессы / узлы должны связываться друг с другом несколько раз.Чтобы минимизировать накладные расходы на установление соединения, я пытаюсь смоделировать MPI-сервер на каждом узле, а затем каждый узел создает соединение с каждым другим узлом в качестве клиента во время запуска.Как только соединения установлены, узлы используют эти соединения для связи друг с другом.
Вот мой рабочий процесс:
- Передача имени кластера от одного узла ко всем другим узлам.
- Все узлы используют MPI_Open_port (MPI_INFO_NULL, port_name) для получения сгенерированного машиной имени порта.
- Все узлы опубликовали свое имя, используя MPI_Publish_name (имя, MPI_INFO_NULL, port_name).«имя» создается как «clusterName-rank».Как только все узлы публикуют свое имя, я выполняю MPI_Barrier для обеспечения публикации имен.Все узлы вызывают MPI_Comm_accept (имя_порта, MPI_INFO_NULL, 0, MPI_COMM_SELF, клиент) для ожидания любого соединения.
- Каждый узел ищет имя для других узлов, используя MPI_Lookup_name (name, MPI_INFO_NULL, c_port_name).Как только он получает имя, он вызывает MPI_Comm_connect (имя_порта, MPI_INFO_NULL, 0, MPI_COMM_SELF, & nodeConnections [i]), чтобы зарегистрировать соединение с ним.
Моя проблема в шаге 4. Я могуполучить имя порта для других процессов, но когда я вызываю MPI_Comm_connect (), MPI выдает ошибку, как показано ниже:
ДВЕ ПОЛУЧИВАЕТСЯ С ТОЛЬКО ЖЕ ПИРОМ [[WILDCARD], WILDCARD] И TAG 300 - ABORTING
Правильно ли я подхожу к проблеме?Если да, может кто-нибудь, пожалуйста, помогите мне, как решить эту проблему.Если нет, не могли бы вы намекнуть мне в правильном направлении?
Вот фрагмент исходного кода, который я использую, если он помогает.
void MPIServer::startServer() {
MPI_Open_port(MPI_INFO_NULL, port_name);
char name[DOMP_MAX_CLIENT_NAME];
snprintf(name, DOMP_MAX_CLIENT_NAME, "%s-%d", clusterName, rank);
MPI_Publish_name(name, MPI_INFO_NULL, port_name);
log("Server %s for node %d available at %s\n", name, rank, port_name);
// First start your own server thread
serverThread = std::thread(&MPIServer::accept, this);
// Wait for all nodes to start their server first
MPI_Barrier(MPI_COMM_WORLD);
// Now create connection to all other threads
char c_port_name[MPI_MAX_PORT_NAME];
for (int i = 0; i < clusterSize; i++) {
if (i != rank) {
snprintf(name, DOMP_MAX_CLIENT_NAME, "%s-%d", clusterName, i);
MPI_Lookup_name(name, MPI_INFO_NULL, c_port_name);
log("Node %d connecting to client %s at port %s\n", rank, name, c_port_name);
MPI_Comm_connect(c_port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &nodeConnections[i]);
}
}
}
// Here is the accept method
void MPIServer::accept() {
while (true) {
MPI_Comm *client = new MPI_Comm();
MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, client);
log("Node %d received a request\b", rank);
// Handle in a new thread
// TODO: Consider using a threadpool instead of spawning thread every time
std::thread(&MPIServer::handleRequest, this, client);
}
}
Вот версия MPI, которую я использую:
-bash-4.2$ ompi_info
Package: Open MPI mockbuild@x86-041.build.eng.bos.redhat.com
Distribution
Open MPI: 1.10.7
Open MPI repo revision: v1.10.6-48-g5e373bf
Open MPI release date: May 16, 2017
Open RTE: 1.10.7
Open RTE repo revision: v1.10.6-48-g5e373bf
Open RTE release date: May 16, 2017
OPAL: 1.10.7
OPAL repo revision: v1.10.6-48-g5e373bf
OPAL release date: May 16, 2017
MPI API: 3.0.0
Ident string: 1.10.7