Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Комунікатори та операції з ними.Содержание книги Поиск на нашем сайте
Комунiкатор надає окремий контекст обмiну процесiв деякої групи. Контекст забезпечує можливiсть незалежних обмiнiв даними. Кожнiй групi процесiв може вiдповiдати кiлька ко- мунiкаторiв, але кожен комунiкатор у будь-який момент часу однозначно вiдповiдає тiльки однiй групi Наступнi комунiкатори створюються вiдразу пiсля виклику MPI_init: • MPI_COMM_WORLD – комунiкатор котрий мiстить всi процеси додатку; • MPI_COMM_NULL – значення, що використовується для помилкового комунiкато- ра; • MPI_COMM_SELF – комунiкатор котрий мiстить тiльки процес котрий його вико- ристав. Створення комунiкатора є колективною операцiєю i вимагає операцiї мiжпроцесорного обмiну, тому такi функцiї мають викликатися всiма процесами деякого iснуючого комунi- катора. int MPI_Comm_dup(MPI_Comm comm, MPI_Comm newcomm); - Створення нового комунiкатора newcomm з тiєю ж групою процесiв що i comm та такими ж атрибутами. int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm newcomm); Створення нового комунiкатора newcomm з процесiв групи group яка має бути пiд- множиною групи пов’язаної з комунiкаторм comm. Виклик повен бути здiйсненний зi всiх процесiв комунiкатора comm. В процесас якi не належать до групи group буде повернуто MPI_COMM_NULL. int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm newcomm); - Розбиття комунiкатора comm на кiлька нових комунiкаторiв по числу значень параме- тра color. В один комунiкатор потрапляють процеси з одним значенням color. Процеси з великим значенням параметра key отримають бiльший ранг в новiй групi, при однаковому значеннi параметра key порядок нумерацiї процесiв вибирається системою.
Декатрова топологія в MPI.
Топологiя – це механiзм спiвставлення процесам деякого комунiкатора альтернативної схеми адресацiї. В МРI топологiї вiртуальнi, тобто вони не пов’язанi з фiзичною топологiєю комунiкацiйної мережi. Топологiя використовується програмiстом для бiльш зручного по- значення процесiв, i таким чином, наближення паралельної програми до структури матема- тичного алгоритму. Крiм того, топологiя може використовуватися системою для оптимiзацiї розподiлу процесiв за фiзичними процесорами використовуваного паралельного комп’ютера за допомогою змiни порядку нумерацiї процесiв усерединi комунiкатора.
В МРI передбачено два типи топологiй: • декартова топологiя (прямокутна решiтка довiльної розмiрностi);
• топологiя графа.
int MPI_Topo_test(MPI_Comm comm, int status); Функцiя визначення типу топологiї, пов’язаної з комунiкатором comm.
int MPI_Cart_create(MPI_Comm comm_old, int ndims, const int dims[], const int periods [], int reorder, MPI_Comm comm_cart); Створення комунiкатора comm_cart, що володiє декартовою топологiєю, з процесiв ко- мунiкатора comm_old
int MPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int coords[]); - Визначення декартових координат процеса по його рану rank в комунiкаторi comm. Вiдрахунок координат в кожному вимiрi починається з нуля. int MPI_Cart_rank(MPI_Comm comm, const int coords[], int rank); - Визначення рангу процеса rank за його декартовими координатами coords. int MPI_Cart_get(MPI_Comm comm, int maxdims, int dims[], int periods[], int coords[]); -Одержання iнформацiї про декартову топологiю котра пов’язана з комунiкатором comm та координат в нiй прцесу, що виклика дану функцiю. maxdims – задає розмiрнiсть топо- логiї. dims – повертає кiлькiсть процесiв для кожого вимiру. periods – перiодичнiсть по кожному вимiру. coords – координати процесу в декартовiй топологiї. int MPI_Cart_shift(MPI_Comm comm, int direction, int disp, int rank_source, int rank_dest); Отримання номерiв посилаючого rank_source i приймаючого rank_dest процесiв в де- картовiй топологiї комунiкатора comm для здiйснення зсуву уздовж вимiру direction на величину disp.
Топологія графа в MPI. int MPI_Graph_create(MPI_Comm comm_old, int nnodes, const int index[], const int edges[], int reorder, MPI_Comm comm_graph);
Створення, на основi комунiкатора comm_old, комунiкатора comm_graph з топологiєю графа. Параметер nnodes задає кiлькiсть вершин графа, index – задає сумарну кiлькiсть сусiдiв для перших вершин. Масив edges мiстить впорядкований список процесiв сусiдiв для всiх вершин. reorder – логiчний параметр, що визначає, чи системi дозволено мiняти порядок нумерацiї процесiв для оптимiзацiї розподiлу процесiв за фiзичними процесорам використовуваного паралельного комп’ютера.Фкнуцiя MPI_Graph_create є колективною, отже повинна бути викликана з кожного ппроцесу комунiкатора comm. Якщо кiлькiсть процесiв в комунiкаторi comm_graph мен- ша вiд кiлькостi у вихiдному екомунiкаторi comm – деяким процесам може повернутись значення MPI_COMM_NULL, а якщо бiльша – виклик буде помилковим.
Для опису такого графа необхiдно заповнити наступнi структури: index[] = {2, 3, 4, 6}; edges[] = {1, 3, 0, 3, 0, 2}; пiсля цього можна створювати топологiю графа (необхiдно не менше чотирьох процесiв). int MPI_Graph_neighbors_count(MPI_Comm comm, int rank, int nneighbors); Визначає кiлькiсть сусiдiв nneighbors прцесу з рангом rank в топологiї графа.
int MPI_Graph_neighbors(MPI_Comm comm, int rank, int maxneighbors, int neighbors[]); Визначеня рангiв безпосереднiх сусiдiв процесу з рангом rank, ранги сусiдiв повертаю- ться в масивi neighbors*+. int MPI_Graphdims_get(MPI_Comm comm, int nnodes, int nedges); - Визначення кiлькостi веошин nnodes та ребер nedges в топологiї графа пов’язаної з комунiкатором comm. int MPI_Graph_get(MPI_Comm comm, int maxindex, int maxedges, int index[], int edges[]); 3 Отримання iнформацiї про топологiю графа, котра пов’язана з комунiкатором comm. В масивах index та edges повертається опис топологiї, maxindex, maxedges – мiстять обмеже- ння на розмiри вiдповiдних масивiв (можна одержати за допомогою MPI_Graphdims_get).
1. Написати приклад MPI програми котра надрукує номера процесів та імена процесорів на котрих працює. Навести команди компіляції та запуску MPI програми. #include <mpi.h> #include <stdio.h> int main(int argc, char **argv) { int size, rank, i; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); char processor_name[MPI_MAX_PROCESSOR_NAME]; int name_len; MPI_Get_processor_name(processor_name, &name_len); if(rank == 0) printf("Total processes count = %d\n", size); printf("I am %d process from %d (%s) processes!\n", rank, size, processor_name); MPI_Finalize(); return 0; }
2. Написати приклад обміну між двома процесами з використанням функцій блокованого обміну. #include <mpi.h> #include <stdio.h> int main(int argc, char **argv) { int nproc, my_rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nproc); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); if (my_rank == 0) { MPI_Send ("Hello proces 1!", 15, MPI_CHAR, 1, 77, MPI_COMM_WORLD); printf("Message send by proc %d.\n", my_rank); } else if (my_rank == 1) { char recv_buffer[15]; MPI_Status status;
MPI_Recv (recv_buffer, 15, MPI_CHAR, 0, 77, MPI_COMM_WORLD, &status); printf("Message received by proc %d.\n", my_rank); printf("Message: %s\n", recv_buffer); } MPI_Finalize(); return 0; } 3. Написати приклад обміну між парними та непарними процесами з використанням функцій блокованого обміну. #include <mpi.h> #include <stdio.h> int main(int argc, char **argv) { int nproc, my_rank;
MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nproc); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); if (my_rank%2 == 0) {
char str[] = "Hello proces %d!"; char str2[20];
sprintf(str2,str,my_rank + 1);
MPI_Send (str2, 20, MPI_CHAR, my_rank + 1, 77, MPI_COMM_WORLD); printf("Message send by proc %d.\n", my_rank); } else if (my_rank%2 == 1) {
char recv_buffer[15]; MPI_Status status;
MPI_Recv (recv_buffer, 20, MPI_CHAR, my_rank - 1, 77, MPI_COMM_WORLD, &status); printf("Message received by proc %d.\n", my_rank); printf("Message: %s\n", recv_buffer);
}
MPI_Finalize();
return 0; }
4. Написати приклад обміну між двома процесами з використанням функцій неблокуючого (асинхронного) обміну.
#include <mpi.h> #include <stdio.h> int main(int argc, char **argv) { int nproc, my_rank;
MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nproc); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); if (my_rank == 0) {
MPI_Request request; MPI_Status status;
MPI_Isend ("Hello proces 1!", 15, MPI_CHAR, 1, 77, MPI_COMM_WORLD, &request); MPI_Wait (&request, &status); printf("Message send by proc %d.\n", my_rank); } else if (my_rank == 1) {
char recv_buffer[15]; MPI_Request request; MPI_Status status;
MPI_Irecv (recv_buffer, 15, MPI_CHAR, 0, 77, MPI_COMM_WORLD, &request); printf("Message received by proc %d.\n", my_rank); MPI_Wait (&request, &status); printf("Message: %s\n", recv_buffer);
}
MPI_Finalize(); return 0; } 5. Написати приклад обміну між парними та непарними процесами з використанням функцій неблокуючого (асинхронного) обміну.
#include <mpi.h> #include <stdio.h> int main(int argc, char **argv) { int nproc, my_rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nproc); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); if (my_rank%2 == 0) {
char str[] = "Hello proces %d!"; char str2[20]; sprintf(str2,str,my_rank + 1);
MPI_Request request; MPI_Status status;
MPI_Isend (str2, 20, MPI_CHAR, my_rank + 1, 77, MPI_COMM_WORLD, &request); MPI_Wait (&request, &status); printf("Message send by proc %d.\n", my_rank); } else if (my_rank%2 == 1) {
char recv_buffer[20]; MPI_Request request;
MPI_Status status;
MPI_Irecv (recv_buffer, 20, MPI_CHAR, my_rank - 1, 77, MPI_COMM_WORLD, &request); printf("Message received by proc %d.\n", my_rank); MPI_Wait (&request, &status); printf("Message: %s\n", recv_buffer); }
MPI_Finalize(); return 0; } 6. Написати приклад створення MPI структури з трьома полями. #include <stdio.h> #include <mpi.h> #include <stdlib.h> #include <stddef.h> typedef struct{ char name[20]; int year; int mark; } UserStruct; int main(int argc, char ** argv){ int NUMBER_OF_PROCS, RANK_OF_CURRENT, NEXT_RANK, PREV_RANK; MPI_Status status; UserStruct us; MPI_Datatype us_type; int len[4] = {10, 1, 1, 1}; MPI_Aint pos[4] = {offsetof(UserStruct, name), offsetof(UserStruct, year), offsetof(UserStruct, mark), sizeof(us) }; MPI_Init(&argc, &argv); MPI_Datatype type[4] = {MPI_CHAR, MPI_INT, MPI_INT, MPI_UB}; MPI_Type_create_struct(4, len, pos, type, &us_type); MPI_Type_commit(&us_type); UserStruct send_buf = {"---------Ваше ім’я-----------", 1994, 4}; UserStruct recv_buf; int size_of_data= 1, msg_tag = 55; MPI_Comm_size(MPI_COMM_WORLD, &NUMBER_OF_PROCS); MPI_Comm_rank(MPI_COMM_WORLD, &RANK_OF_CURRENT); NEXT_RANK = RANK_OF_CURRENT == NUMBER_OF_PROCS - 1? MPI_PROC_NULL: RANK_OF_CURRENT + 1; PREV_RANK = RANK_OF_CURRENT == 0? MPI_PROC_NULL: RANK_OF_CURRENT - 1; MPI_Sendrecv(&send_buf, size_of_data, us_type, NEXT_RANK, msg_tag, &recv_buf, size_of_data, us_type, PREV_RANK, msg_tag, MPI_COMM_WORLD, &status); printf("Proc: %d, From: %d, To: %d, Name: %s, Year: %d, Mark: %d \n", RANK_OF_CURRENT, PREV_RANK, NEXT_RANK, recv_buf.name, recv_buf.year, recv_buf.mark); MPI_TYPE_FREE(&us_type) MPI_Finalize(); return 0; }
7. Написати приклад пересилки прийому запакованих типiв даних #include "mpi.h" #include <stdio.h>
int main(int argc, char *argv[]) { int rank, size; int i; char c[100]; char buffer[110]; int position = 0; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); if (size < 2) { printf("Please run with 2 processes.\n");fflush(stdout); MPI_Finalize(); return 1; } MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0) { for (i=0; i<100; i++) c[i] = i; i = 123; MPI_Pack(&i, 1, MPI_INT, buffer, 110, &position, MPI_COMM_WORLD); MPI_Pack(c, 100, MPI_CHAR, buffer, 110, &position, MPI_COMM_WORLD); MPI_Send(buffer, position, MPI_PACKED, 1, 100, MPI_COMM_WORLD); } if (rank == 1) { MPI_Recv(buffer, 110, MPI_PACKED, 0, 100, MPI_COMM_WORLD, &status); MPI_Unpack(buffer, 110, &position, &i, 1, MPI_INT, MPI_COMM_WORLD); MPI_Unpack(buffer, 110, &position, c, 100, MPI_CHAR, MPI_COMM_WORLD); printf("i=%d\nc[0] = %d\n...\nc[99] = %d\n", i, (int)c[0], (int)c[99]);fflush(stdout); }
MPI_Finalize(); return 0; } 8. Написати приклад обміну між всіма процесами з використанням функції MPI_Bcast. #include <stdio.h> #include <mpi.h> #define N 5 int main(int argc, char** argv) { int rank, size; char* msg; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if(rank == 0){ msg = "Heil to all!"; } MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(&msg, 11, MPI_CHAR, 0, MPI_COMM_WORLD);
if(rank!= 0) { printf("Proc %d received\t: %s \nProc %d says\t: Heil master process!\n", rank, msg, rank); } MPI_Finalize(); return 0; }
9. Написати приклад додавання квадратних матриць з використанням колективних функцій. #include <stdio.h> #include <mpi.h> #define N 5 int main(int argc, char** argv) { int rank, i, j, size; double Mtx1[N][N], Mtx2[N][N], Mtx_sum[N][N]; double row1[N], row2[N], row_sum[N]; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { for (i=0; i<N; i++) for (j=0; j<N; j++) {
Mtx1[i][j]=(i-2)*(j-5); Mtx2[i][j]=(i-2)*(j-5); } } MPI_Scatter(Mtx1, N, MPI_DOUBLE, row1, N, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Scatter(Mtx2, N, MPI_DOUBLE, row2, N, MPI_DOUBLE, 0, MPI_COMM_WORLD); for (i = 0; i < N; i++) { row_sum[i] = row1[i] + row2[i]; if(rank == 0)printf("%d, max %lf\n", rank, row_sum[i]); } MPI_Gather(row_sum, N, MPI_DOUBLE, Mtx_sum, N, MPI_DOUBLE, 0, MPI_COMM_WORLD);
if (rank == 0) { for (i=0; i<N; i++) { for (j=0; j<N; j++) { printf("%lf\t", Mtx_sum[i][j]); } printf("\n"); } }
MPI_Finalize(); return 0; }
10. Написати приклад знаходження суми максимальних елементiв рядкiв матриці з використанням колективних функцій. #include <stdio.h> #include <mpi.h> #define N 5 int main(int argc, char** argv) { int rank, i, j, size; double Mtx[N][N], c[N]; double row[N]; double max_row, sum; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { for (i=0; i<N; i++) for (j=0; j<N; j++) Mtx[i][j]=(i-2)*(j-5); } MPI_Scatter(Mtx, N, MPI_DOUBLE, row, N, MPI_DOUBLE, 0, MPI_COMM_WORLD); max_row = row[0]; for (i = 0; i < N; i++) { if (row[i]>max_row) { max_row = row[i]; } } printf("%d, max %lf\n", rank, max_row); MPI_Gather(&max_row, 1, MPI_DOUBLE, c, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); if (rank == 0) { sum = 0; for (i=0; i<N; i++) sum += c[i]; printf("Sum of max row element: %lf \n",sum); } MPI_Finalize(); return 0; }
11. Написати приклад знаходження суми елементiв матриці з використанням функції MPI_Reduce. #include <stdio.h> #include <mpi.h> #define N 5 int main(int argc, char** argv) {
int rank, i, j, size; double Mtx[N][N], a[N], b[N];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank);
for(i = 0; i < N; i++) for(j = 0; j < N; j++) Mtx[i][j] = 1;//(i-2)*(j-5);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Allreduce(Mtx, a, N, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); MPI_Reduce(a, b, N, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (rank==0) printf("Sum=%lf\n",b[0]);
MPI_Finalize();
return 0; } 12. Написати приклад знаходження максимума елементiв вектора з використанням функції MPI_Reduce. #include <stdio.h> #include <mpi.h> #define N 10 int main(int argc, char** argv) { int rank, i, size; double a[N], b[N];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank);
for(i = 0; i < N; i++) a[i] = -(i-2)*(i-2); MPI_Barrier(MPI_COMM_WORLD);
MPI_Reduce(a, b, N, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
if (rank==0) printf("Max=%lf\n",b[0]);
MPI_Finalize();
return 0; }
|
||||||||
Последнее изменение этой страницы: 2017-01-20; просмотров: 324; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.221.221.171 (0.012 с.) |