Мегаобучалка Главная | О нас | Обратная связь


Сложные типы данных в MPI



2015-11-27 667 Обсуждений (0)
Сложные типы данных в MPI 0.00 из 5.00 0 оценок




 

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

Последовательность исходных типов, которые тоже могут быть составными

Последовательность смещений в байтах

 

Смещения не обязательно должны быть положительными, различными, или идти по возрастанию. Таким образом, порядок отслылаемых элементов может не совпадать с порядком их хранения.

Создание новых типов данных

int MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype)

 

По адресу newtype создает тип данных, каждый элемент которого представляет собой countэлементов типа oldtype, расположенных подряд

int MPI_Type_vector(int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype)

count — число блоков объектов типа oldtype, из которых состоит один объект типа *newtype;

oldtype — исходный тип

blocklength — число элементов типа oldtype в одном блоке

stride — расстояние между блоками в размерах типа oldtype

newtype — адрес, по которому создается новый тип.

int MPI_Type_hvector(int count, int blocklength, MPI_Aint stride, MPI_Datatype oldtype, MPI_Datatype *newtype)

count — число блоков объектов типа oldtype, из которых состоит один объект типа *newtype;

oldtype — исходный тип

blocklength — число элементов типа oldtype в одном блоке

stride — расстояние между блоками в байтах

newtype — адрес, по которому создается новый тип.

 

Для конструирования типа, состоящего из блоков с разным числом элементов, отстоящих друг от друга на разное расстояние, используется следующая пара функций:

int MPI_Type_indexed(int count, int *array_of_blocklengths, int *array_of_displacements,

MPI_Datatype oldtype, MPI_Datatype *newtype)

count — число блоков объектов типа oldtype, из которых состоит один объект типа *newtype;

array_of_blocklengths — массив длин блоков;

array_of_displacements — массив расстояний между блоками в в размерах типа oldtype;

oldtype — исходный тип

newtype — адрес, по которому создается новый тип.

 

int MPI_Type_hindexed(int count, int *array_of_blocklengths, MPI_Aint *array_of_displacements,

MPI_Datatype oldtype, MPI_Datatype *newtype)

count — число блоков объектов типа oldtype, из которых состоит один объект типа *newtype;

array_of_blocklengths — массив длин блоков;

array_of_displacements — массив расстояний между блоками в байтах;

oldtype — исходный тип

newtype — адрес, по которому создается новый тип.

 

 

Для создания нового типа из нескольких различных существующих типов используется следующая функция

int MPI_Type_struct(int count, int *array_of_blocklengths, MPI_Aint *array_of_displacements,

MPI_Datatype* array_of_types, MPI_Datatype *newtype)

count — число элементов в массивах;

array_of_blocklengths — массив длин блоков;

array_of_displacements — массив расстояний между блоками в байтах;

array_of_types — массив исходных типов

newtype — адрес, по которому создается новый тип.

 

 

Прежде, чем использовать новый тип, необходимо вызвать следующую функцию:

int MPI_Type_commit(MPI_Datatype *datatype)

 

По завершению работы с типом необходимо вызвать

int MPI_Type_free(MPI_Datatype *datatype)

MPI_LB и MPI_UB

Иногда необходимо явно определять верхнюю и нижнюю границы области памяти, занимаемой типом (как в следующем примере). Для этого существуют встроенные типы MPI_LB и MPI_UB Нижняя граница области памяти определяется следующим образом:

if(ни один подтип не lb)

lb(typemap)=min (disp[j]);

else

lb(typemap)=min (disp[j], type[j]==lb)

Верхняя граница определяется аналогично:

if(ни один подтип не ub)

lb(typemap)= max(disp[j]);

else

lb(typemap)=max(disp[j], type[j]==ub)

 

Пример: Умножение матрицы на матрицу с использованием типов данных для строки и столбца

#include<mpi.h>

#include <stdio.h>

#include<stdlib.h>

int main(int argc, char** argv)

{

int rows;

int rank,size,sizeofrow,sizeoffloat, blen[2],disp[2];

float* matrix1,*matrix2,*result;

float* lm1,*lm2,*lr;

int* counts, *displs;

int offset;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD,&rank);

MPI_Comm_size(MPI_COMM_WORLD,&size);

MPI_Datatype row,column[2],tosend;

if(argc!=2)

{

if(!rank)

fprintf(stderr,"usage: matrixfragment filename\n");

exit(1);

}

if(!rank)

{

freopen(argv[1],"r",stdin);

scanf("%d",&rows);

matrix1= (float*)malloc(sizeof(float)*rows*rows);

matrix2= (float*)malloc(sizeof(float)*rows*rows);

for(int i=0;i<rows*rows;i++)

scanf("%f",matrix1+i);

for(int i=0;i<rows*rows;i++)

scanf("%f ",matrix2+i);

result=(float*)malloc(sizeof(float)*rows*rows);

}

else

{

matrix1=NULL;

matrix2=NULL;

}

MPI_Bcast(&rows,1,MPI_INT,0,MPI_COMM_WORLD);

lm1=(float*)malloc(sizeof(float)*rows*rows);

lm2=(float*)malloc(sizeof(float)*rows*rows);

lr=(float*)malloc(sizeof(float)*rows*rows);

displs= (int*)malloc(sizeof(int)*size);

counts= (int*)malloc(sizeof(int)*size);

MPI_Type_contiguous(rows,MPI_FLOAT,&row);

MPI_Type_vector(rows,1,rows,MPI_FLOAT,column);

MPI_Type_commit(&row);

MPI_Type_commit(column);

MPI_Type_extent(MPI_FLOAT, &sizeoffloat);

blen[0] = 1;

blen[1] = 1;

disp[0] = 0;

disp[1] = sizeoffloat;

column[1] = MPI_UB;

MPI_Type_struct(2, blen, disp, column, &tosend);

MPI_Type_commit(&tosend);

for(int i=0;i<size;i++)

{

counts[i]=(rows/size +(i<(rows%size)));

displs[i]=0;

for(int j=0;j<i;j++)

displs[i]+=counts[j];

}

 

MPI_Scatterv(matrix1,counts,displs,row,

lm1,counts[rank],row,0,MPI_COMM_WORLD);

MPI_Scatterv(matrix2,counts,displs,tosend,

lm2,counts[rank],row,0,MPI_COMM_WORLD);

for(int i=0;i<counts[rank];i++)

for(int j=0;j<rows;j++)

lr[i*rows+j]=0;

for(int k=0;k<size;k++)

{

offset=(displs[(rank-k+size)%size]);

for (int i=0;i<counts[rank];i++)

for (int j=0;j<counts[(rank-k+size)%size];j++)

{

for(int l=0;l<rows;l++)

{

lr[i*rows+j+offset]+=lm1[i*rows+l]*lm2[j*rows+l];

}

}

MPI_Send(lm2,counts[(rank-k+size)%size],row,(rank+1)%size,k,MPI_COMM_WORLD);

MPI_Recv(lm2,counts[(rank+size-k-1)%size],row,(rank-1+size)%size,k,MPI_COMM_WORLD,MPI_STATUS_IGNORE);

}

MPI_Gatherv(lr, counts[rank], row,

result, counts, displs, row, 0, MPI_COMM_WORLD);

if(!rank)

{

printf("====================\n");

for(int i=0;i<rows;i++)

{

for(int j=0;j<rows;j++)

printf("%g ",result[i*rows+j]);

printf("\n");

}

//*/

free( matrix1);

free (matrix2);

free (result);

}

free (lm1);

free (lm2);

free (lr);

MPI_Finalize();

return 0;

}

;

 

 

Задание 7

 

Написать программу умножения матриц в топологии «двумерная решетка» с использованием типов данных для столбца и минора матрицы.



2015-11-27 667 Обсуждений (0)
Сложные типы данных в MPI 0.00 из 5.00 0 оценок









Обсуждение в статье: Сложные типы данных в MPI

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Личность ребенка как объект и субъект в образовательной технологии: В настоящее время в России идет становление новой системы образования, ориентированного на вхождение...
Почему люди поддаются рекламе?: Только не надо искать ответы в качестве или количестве рекламы...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (667)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.005 сек.)