Источник: http://www.software.unn.ac.ru.
Краткое описание схемы параллельной реализации
Рассматриваемая реализация теста LinPack написана на Microsoft Visual C++.
Функция main имеет следующее описание:
int main(int argc, char *argv[])
В ее теле определяются основные переменные:
MPI_Comm comm; // коммуникатор процессоров
PLA_Obj A = NULL, x = NULL, b = NULL, // матрица A, вектор решения и вектор правых частей
A_append; // матрица A, объединенная с вектором b
double operation_count, // количество "существенных" операций
start_time, // время начала некоторой фазы теста
create_time, // время, затраченное на создание задачи
factor_time, // время, затраченное на факторизацию
solve_time, // время, затраченное на решение задачи
gflops, // полученная производительность
time; // время окончания некоторой фазы теста
int size, // размер задачи
me, nprocs, // идентификатор процессора и общее количество процессоров
nprows, npcols; // число строк и столбцов матрицы
MPI_Datatype datatype; // тип элементов матрицы A и вектора b
После определения переменных происходит инициализация MPI:
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &me);
Затем, на ведущем процессоре(идентификатор которого равен нулю) производится анализ параметров командной строки и ведется их рассылка остальным процессорам с помощью функции MPI_BCast, после чего для созданного коммуникатора comm инициализируется PlaPack:
PLA_Init(comm);
После инициализации PlaPack можно создавать математические объекты:
datatype = MPI_DOUBLE;
PLA_Matrix_create( datatype, size, size+1,
templ, PLA_ALIGN_FIRST, PLA_ALIGN_FIRST, &A_append );
PLA_Mvector_create( datatype, size, 1, templ, PLA_ALIGN_FIRST, &x );
PLA_Mvector_create( datatype, size, 1, templ, PLA_ALIGN_FIRST, &b );
Создаем задачу, то есть заполняем матрицу A и вектор b, а также засекаем время создания:
start_time = MPI_Wtime( );
create_problem( A, x, b );
create_time = MPI_Wtime( ) - start_time;
Затем матрицу A и вектор b объединяем в объекте A_append, используя процедуру PLA_Copy. После создания проводим LU-факторизацию, также засекая время:
start_time = MPI_Wtime();
info = PLA_LU( A_append );
factor_time = MPI_Wtime() - start_time;
Результат разложения будет находиться в матрице A_append. Выделяем из этого объекта матрицы L и U и записываем их в A, также используя процедуру PLA_Copy. Теперь мы можем решить систему:
start_time = MPI_Wtime();
PLA_Trsv( PLA_UPPER_TRIANGULAR, PLA_NO_TRANSPOSE, PLA_NONUNIT_DIAG, A, b );
solve_time = MPI_Wtime() - start_time;
На ведущем процессоре вычисляем производительность:
operation_count = 2.0/3.0 * size * size * size;
time = factor_time + solve_time;
gflops = operation_count / (time*1000000000.0);
Затем записываем данные эксперимента в файл и завершаем работу:
PLA_Obj_free(&A);
PLA_Obj_free(&x);
PLA_Obj_free(&b);
PLA_Obj_free(&A_append);
PLA_Finalize( );
MPI_Finalize( );