2015-09-28 2 views
1

Я пытаюсь создать звездообразную топологию с использованием MPI_Comm_split, но, похоже, у меня есть и проблема, когда я пытаюсь установить ссылки, связанные со всеми процессами. Ожидается, что процессы будут связаны с p0 MPI_COMM_WORLD. Проблема в том, я получаю сбой в линииДизайн виртуальной топологии MPI

error=MPI_Intercomm_create( MPI_COMM_WORLD, 0, NEW_COMM, 0 ,create_tag, &INTERCOMM); 

Ошибка является: MPI_ERR_COMM: invalid communicator.

У меня есть и идея причины, хотя я не знаю, как это исправить. Кажется, это связано с вызовом нулевого процесса, который не принадлежит новому коммуникатору (NEW_COMM). Я попытался поставить оператор if, чтобы остановить выполнение этой строки, если process = 0, но это снова не удается с его коллективного вызова.

Любые предложения будут оценены.

#include <iostream> 
#include "mpi.h" 

using namespace std; 


int main(){ 

MPI_Comm NEW_COMM , INTERCOMM; 
MPI_Init(NULL,NULL); 
int world_rank , world_size,new_size, error; 

error = MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 
error = MPI_Comm_size(MPI_COMM_WORLD,&world_size); 

int color = MPI_UNDEFINED; 
if (world_rank > 0) 
    color = world_rank ; 

error = MPI_Comm_split(MPI_COMM_WORLD, color , world_rank, &NEW_COMM); 

int new_rank; 
if (world_rank > 0) { 
     error = MPI_Comm_rank(NEW_COMM , &new_rank); 
     error = MPI_Comm_size(NEW_COMM, &new_size); 
    } 
    int create_tag = 99; 

    error=MPI_Intercomm_create( MPI_COMM_WORLD, 0, NEW_COMM, 0 ,create_tag, &INTERCOMM); 

if (world_rank > 0) 
    cout<<" My Rank in WORLD = "<< world_rank <<" New rank = "<<new_rank << " size of NEWCOMM = "<<new_size <<endl; 
else 
    cout<<" Am centre "<<endl; 


    MPI_Finalize(); 

    return 0; 


} 
+0

Я мог ошибаться, но я считаю, что 'MPI_Intercomm_create' принимает в качестве входных данных два _intracommicators_. Как и вы, вы даете ему MPI_COMM_WORLD и NEW_COMM; один коммуникатор является подмножеством другого. Я считаю, что вы должны создать второй коммуникатор, который является только процессом 'world_rank == 0':' ROOT_COMM'. Затем вызывается 'MPI_Intercomm_create (ROOT_COMM, 0, NEW_COMM, 0, create_tag и INTERCOMM);' может работать как ожидалось. – NoseKnowsAll

ответ

1

Как насчет использования топологии MPI? Что-то вроде этого:

#include <mpi.h> 
#include <iostream> 

int main(int argc, char *argv[]) { 
    MPI_Init(&argc, &argv); 
    int rank, size; 

    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    int indegree, outdegree, *sources, *sourceweights, *destinations, *destweights; 

    if (rank == 0) { //centre of the star 
     indegree = outdegree = size - 1; 
     sources = new int[size - 1]; 
     sourceweights = new int[size - 1]; 
     destinations = new int[size - 1]; 
     destweights = new int[size - 1]; 
     for (int i = 0; i < size - 1; i++) { 
      sources[i] = destinations[i] = i + 1; 
      sourceweights[i] = destweights[i] = 1; 
     } 
    } 
    else { // tips of the star 
     indegree = outdegree = 1; 
     sources = new int[1]; 
     sourceweights = new int[1]; 
     destinations = new int[1]; 
     destweights = new int[1]; 
     sources[0] = destinations[0] = 0; 
     sourceweights[0] = destweights[0] = 1; 
    } 

    MPI_Comm star; 
    MPI_Dist_graph_create_adjacent(MPI_COMM_WORLD, indegree, sources, sourceweights, 
            outdegree, destinations, destweights, MPI_INFO_NULL, 
            true, &star); 
    delete[] sources; 
    delete[] sourceweights; 
    delete[] destinations; 
    delete[] destweights; 

    int starrank; 

    MPI_Comm_rank(star, &starrank); 

    std::cout << "Process #" << rank << " of MPI_COMM_WORLD is process #" << starrank << " of the star\n"; 

    MPI_Comm_free(&star); 

    MPI_Finalize(); 

    return 0; 
} 

Это то, что вам нужно после? Если нет, для чего нужен ваш коммуникатор?


EDIT: Пояснение о MPI топологий

Я хотел бы уточнить, что, даже если этот график коммуникатор представлен как таковой, он не отличается от MPI_COMM_WORLD в большинстве аспектов. Примечательно, что он включает весь набор MPI-процессов, первоначально представленных в MPI_COMM_WORLD. Действительно, хотя его звездная форма определена и мы не представляли никакой связи между процессом № 1 и процессом № 2, например, , ничто не мешает вам совершать связь точка-точка между этими двумя процессами. Просто, определяя эту топологию графа, вы даете указание на тип связи, который ваш код будет раскрывать. Затем вы попросите библиотеку попытаться изменить порядок рядов на физических узлах, чтобы найти подходящее соответствие между физическим расположением вашего компьютера/сети и потребностями, которые вы выражаете. Это можно сделать внутренне с помощью алгоритма, минимизирующего функцию стоимости с использованием, например, моделируемого метода отжига, но это дорого. Более того, это предполагает, что фактическая компоновка сети доступна где-то в библиотеке (что обычно не так). Поэтому в конце дня, в большинстве случаев, эта фаза оптимизации размещения просто игнорируется, и вы получаете те же индексы, что и те, которые вы ввели ... Только я знаю о некоторых сетчатых/торообразных сетевых сетях чтобы фактически выполнить этап размещения для MPI_Car_create(), но, возможно, я устарел от этого.

В любом случае, суть в том, что я понимаю, что вы хотите играть с коммуникаторами для обучения, но не ожидайте слишком многого из них. Лучше всего узнать здесь, как получить те, которые вы хотите, в наименьших и простых возможных вызовах, и я надеюсь, что я предлагаю.

+0

да, спасибо. Это похоже на тип топологии, который я искал, так как мне нужен только один центральный процесс для распространения информации. Ваше решение довольно чистое и короткое. Я думал, однако, о более явном способе, то есть добавить процесс к своему собственному коммуникатору, а затем рассказать ему, кто является корневым/центральным процессом.Причина, на которую я смотрю, заключается в том, что я хотел бы цементировать свое умение создавать любую другую топологию в будущем. – Walker

+1

Я попытался в редактировании, чтобы немного ответить на это. – Gilles

Смежные вопросы