|
Пошаговое руководство. Запуск отладчика MPI-кластера в Visual Studio 2010
Visual Studio 2010
В этом пошаговом руководстве описано, как настроить и запустить сеанс отладчика MPI-кластера на локальном компьютере и в кластере Microsoft Windows HPC Server 2008. Руководство также содержит процедуры и пример кода, которые необходимы для создания приложения, использующего интерфейс передачи сообщений (MPI) и API-интерфейс OpenMP (Open Multi-Processing).
Содержание руководства
· Требования для использования отладчика MPI-кластера
· Создание образца проекта MPI на C++ в Visual Studio 2010
· Настройка и запуск отладчика MPI-кластера
· Приложение. Файлы, развертываемые Visual Studio в дополнение к двоичным файлам приложения (и CRT по запросу)
Требования для использования отладчика MPI-кластера
· На компьютере разработчика должна быть установлена среда Visual Studio 2010 Professional Edition или более высокой версии (с удаленным отладчиком).
· У пользователя должны быть права администратора кластера.
· У Visual Studio должен быть доступ ко всем вычислительным узлам, на которых предполагается запускать сеансы отладки. Необходимый доступ обеспечивают сценарии, указанные ниже.
· Приложение разрабатывается на головном узле кластера или на выделенном узле входа.
· Используется кластер, в котором вычислительные узлы подключены к корпоративной сети (топология 2, 4 или 5), а компьютер разработчика присоединен к тому же домену или к домену, для которого настроены отношения доверия с доменом кластера.
· Для отправки приложения в кластер HPC с клиентского компьютера необходимо установить пакет Microsoft HPC Pack 2008.
· Для построения MPI-программ с использованием интерфейса передачи сообщений корпорации Майкрософт необходимо, чтобы на компьютере разработчика был установлен пакет Windows HPC Server 2008 SDK.
Создание образца проекта MPI на C++ в Visual Studio 2010
Пример кода, приведенный в этом разделе, предназначен для создания параллельного приложения, вычисляющего значение числа пи с использованием моделирования методом Монте-Карло.
Этот пример кода выполняет 50 000 000 итераций в каждом процессе MPI. При каждой итерации генерируются случайные числа в интервале [0;1] для определения набора координат x и y. Набор координат оценивается для определения того, попадает ли точка в область, ограниченную линией с уравнением x 2 + y 2 = 1. Если точка попадает в эту область, значение переменной count увеличивается на единицу. Значения count из каждого процесса MPI суммируются, и результат присваивается переменной result. Общее количество точек, попавших в область (result), умножается на четыре и делится на общее количество итераций для получения приблизительного значения числа пи.
Приведенная ниже процедура содержит две реализации метода Монте-Карло.
· В первом примере используются интерфейсы MPI и OpenMP. Дополнительные сведения об интерфейсе OpenMP см. по ссылке OpenMP in Visual C++.
· Во втором примере используются интерфейс MPI и библиотека PPL (Parallel Patterns Library). Дополнительные сведения о библиотеке PPL см. по ссылке Parallel Patterns Library (PLL).
Создание образца проекта
1. Запустите Visual Studio 2010.
2. Создайте консольное приложение Win32 на C++ с именем ParallelPI. Используйте проект без предкомпилированных заголовков.
3. Задайте дополнительные свойства проекта.
Копировать
C:\Program Files\Microsoft HPC Pack 2008 SDK\Include;Копировать
C:\Program Files\Microsoft HPC Pack 2008 SDK\Lib\i386;Например, если необходимо построить и отладить 64-разрядное приложение, введите следующее:
Копировать
C:\Program Files\Microsoft HPC Pack 2008 SDK\Lib\amd64;4. В главном исходном файле выделите весь код и удалите его.
5. Вставьте в пустой исходный файл один из приведенных ниже примеров кода. В первом примере используются интерфейсы MPI и OpenMP, а во втором — интерфейс MPI и библиотека PPL.
В приведенном ниже примере кода используются интерфейсы MPI и OpenMP. Функция ThrowDarts использует параллельный цикл for интерфейса OpenMP для задействования процессоров с несколькими ядрами, если они доступны.
// ParallelPI.cpp: Defines the entry point for the MPI application.//#include "mpi.h"#include "stdio.h"#include "stdlib.h"#include "limits.h"#include "omp.h"#include <random> int ThrowDarts(int iterations){std::tr1::uniform_real<double> MyRandom;std::tr1::minstd_rand0 MyEngine; double RandMax = MyRandom.max();int count = 0;omp_lock_t MyOmpLock; omp_init_lock(&MyOmpLock);//Compute approximation of pi on each node#pragma omp parallel forfor(int i = 0; i < iterations; ++i){double x, y;x = MyRandom(MyEngine)/RandMax;y = MyRandom(MyEngine)/RandMax; if(x*x + y*y < 1.0){omp_set_lock(&MyOmpLock);count++;omp_unset_lock(&MyOmpLock);}} omp_destroy_lock(&MyOmpLock); return count;} int main(int argc, char* argv[]){int rank;int size;int iterations;int count;int result;double time;MPI_Status s; MPI_Init(&argc, &argv);MPI_Comm_rank(MPI_COMM_WORLD,&rank);MPI_Comm_size(MPI_COMM_WORLD,&size); if(rank == 0){//Rank 0 asks the number of iterations from the user.iterations = 50000000;if(argc > 1){iterations = atoi(argv[1]);}printf("Executing %d iterations.\n", iterations);fflush(stdout);}//Broadcast the number of iterations to execute.if(rank == 0){for(int i = 1; i < size; ++i){MPI_Ssend(&iterations, 1, MPI_INT, i, 0, MPI_COMM_WORLD);}}else{MPI_Recv(&iterations, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &s);} //MPI_Bcast(&iterations, 1, MPI_INT, 0, MPI_COMM_WORLD); count = ThrowDarts(iterations); //Gather and sum resultsif(rank!= 0){MPI_Ssend(&count, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);}else{for(int i = 1; i < size; ++i){int TempCount = 0;MPI_Recv(&TempCount, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &s);count += TempCount;}}result = count; //MPI_Reduce(&count, &result, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if(rank == 0){printf("The value of PI is approximated to be: %16f", 4*((float)result/(float)(iterations*size)));} MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize();return 0;}
В приведенном ниже примере кода используются библиотека PPL вместо интерфейса OpenMP и групповые операции MPI вместо операций "точка-точка".
// ParallelPI.cpp: Defines the entry point for the MPI application.//#include "mpi.h"#include "stdio.h"#include "stdlib.h"#include "limits.h"#include <ppl.h>#include <random>#include <time.h> using namespace Concurrency; int ThrowDarts(int iterations){ combinable<int> count; int result = 0; parallel_for(0, iterations, [&](int i){ std::tr1::uniform_real<double> MyRandom;double RandMax = MyRandom.max();std::tr1::minstd_rand0 MyEngine;double x, y; MyEngine.seed((unsigned int)time(NULL)); x = MyRandom(MyEngine)/RandMax;y = MyRandom(MyEngine)/RandMax; if(x*x + y*y < 1.0){count.local() += 1;}}); result = count.combine([](int left, int right) { return left + right; }); return result;} void main(int argc, char* argv[]){int rank;int size;int iterations;int count;int result; MPI_Init(&argc, &argv);MPI_Comm_rank(MPI_COMM_WORLD,&rank);MPI_Comm_size(MPI_COMM_WORLD,&size); if(rank == 0){//Rank 0 reads the number of iterations from the command line.//50M iterations is the default.iterations = 50000000;if(argc > 1){iterations = atoi(argv[argc-1]);}printf("Executing %d iterations on %d nodes.\n", iterations, size);fflush(stdout);}//Broadcast the number of iterations to execute.MPI_Bcast(&iterations, 1, MPI_INT, 0, MPI_COMM_WORLD); count = ThrowDarts(iterations); //Gather and sum resultsMPI_Reduce(&count, &result, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if(rank == 0){printf("The value of PI is approximated to be: %16f", 4*((double)result/(double)(iterations*size)));} MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); }6. В меню Файл выберите пункт Сохранить все.
7. В меню Построение выберите пункт Перестроить решение.
Дата добавления: 2015-09-12; просмотров: 334 | Поможем написать вашу работу | Нарушение авторских прав |