2013-02-28 7 views
1

Я осмотрел все вокруг, но не смог найти ссылки на эту проблему.модуль повышения напряжения не может вызвать функцию mpi

Я написал программу на C++, которую я тестирую с помощью boost/unit. Серийная версия работает нормально, и модульный тест работает.
Теперь я сделал программу параллельной с помощью функции, выполняющей неловко параллельную работу с MPI. Если записать мой собственный тест, вызывающий параллельную функцию - назовем его parafunction - он работает хорошо, MPI работает правильно.
Компиляция выполняется с помощью mpiC++, и я использую mpixec для запуска программы.

Если я вызываю парафункцию в тестовом случае с усилением, MPI идет не так, тест запускается несколько раз, и процесс вызывается, когда вызываются несколько MPI::Init. Вот пример ошибки я получаю:

Функция MPI_Comm_size() была вызвана после того, как MPI_FINALIZE был вызван.

Это запрещено стандартом MPI.

Ваша работа MPI будет отменена.

Мой тестовый пример находится на test_unit, автоматически обрабатывается master_test_suite. Как я сказал без параллелизации, он работает отлично.

Parafunction вызывает MPI::Init и MPI::Finalize, и никакая другая функция файлов не должна выполнять какие-либо материалы, связанные с MPI.

С кем-либо сталкивались с подобной проблемой раньше?

Мой пробный прогон довольно длинный, поэтому я действительно мог использовать параллельную версию моей программы!

Спасибо за вашу помощь

+0

И то же самое происходит, если я выполняю все параллелизацию внутри моего BOOST_AUTO_TEST_CASE вместо вызова parafunction ... –

ответ

1

функция, которая как инициализируется, а затем Завершает можно назвать только один раз, потому что MPI может быть только инициализируется один раз в течение срока действия программы, и может быть завершена только один раз. Чтобы предотвратить несколько вызовов инициализации, поставить вызов MPI_Init() или MPI_Init_thread() в условном:

int already_initialised; 

MPI_Initialized(&already_initialised); 
if (!already_initialised) 
    MPI_Init(NULL, NULL); 

Что касается завершения, он должен быть перемещен за пределы вашей функции, вероятно, в atexit(3) обработчика, если вы этого не сделаете хотите загрязнять внешнюю область с помощью вызовов MPI. Например:

void finalise_mpi(void) 
{ 
    int already_finalised; 

    MPI_Finalized(&already_finalised); 
    if (!already_finalised) 
     MPI_Finalize(); 
} 

... 
atexit(finalise_mpi); 
... 

atexit() вызова может быть частью коды инициализации, например .:

int already_initialised; 

MPI_Initialized(&already_initialised); 
if (!already_initialised) 
{ 
    MPI_Init(NULL, NULL); 
    atexit(finalise_mpi); 
} 

Это не будет устанавливать atexit(3) обработчика, если MPI уже инициализирован. Основная идея заключается в том, что если MPI был инициализирован при входе в функцию, это означало бы, что MPI_Init() был вызван во внешней области, и обычно можно ожидать, что MPI_Finalize() также называется там.

Если бы я был вами, я бы переместил инициализацию MPI и финализацию из функции параллельной обработки.Правильной вызывающей последовательностью будет инициализация MPI, запуск тестов, а затем завершение MPI.

Я использовал привязки C в приведенном выше тексте, поскольку привязки C++ устарели в MPI-2.2, а затем удалены в MPI-3.0.