Проектирование виртуальной топологии MPI

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

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

Ошибка: MPI_ERR_COMM: invalid communicator ,

У меня есть и представление о причине, хотя я не знаю, как это исправить. Похоже, это связано с вызовом по нулевому процессу, который не принадлежит новому коммуникатору (NEW_COMM). Я попытался поместить оператор if, чтобы остановить выполнение этой строки, если процесс = 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;}

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;
}

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


РЕДАКТИРОВАТЬ: Объяснение топологий MPI

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

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]