MPI клиент / сервер - PullRequest
       11

MPI клиент / сервер

3 голосов
/ 26 апреля 2019

У меня есть ситуация, когда все процессы / узлы должны связываться друг с другом несколько раз.Чтобы минимизировать накладные расходы на установление соединения, я пытаюсь смоделировать MPI-сервер на каждом узле, а затем каждый узел создает соединение с каждым другим узлом в качестве клиента во время запуска.Как только соединения установлены, узлы используют эти соединения для связи друг с другом.

Вот мой рабочий процесс:

  1. Передача имени кластера от одного узла ко всем другим узлам.
  2. Все узлы используют MPI_Open_port (MPI_INFO_NULL, port_name) для получения сгенерированного машиной имени порта.
  3. Все узлы опубликовали свое имя, используя MPI_Publish_name (имя, MPI_INFO_NULL, port_name).«имя» создается как «clusterName-rank».Как только все узлы публикуют свое имя, я выполняю MPI_Barrier для обеспечения публикации имен.Все узлы вызывают MPI_Comm_accept (имя_порта, MPI_INFO_NULL, 0, MPI_COMM_SELF, клиент) для ожидания любого соединения.
  4. Каждый узел ищет имя для других узлов, используя 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
...