Уровень алгоритма

Участник:Руфина Третьякова/Хранение ненулевых элементов разреженных матриц. Умножение разреженной матрицы на вектор: различия между версиями

Материал из Алговики
Перейти к навигации Перейти к поиску
Строка 108: Строка 108:
*Каждый процессор оперирует с <math>\frac{n}{k}</math> строками, в каждой из которых примерно <math>\frac{nnz}{n}</math> элементов. Параллельная сложность алгоритма - <math>O(\frac{nnz}{k})</math>
*Каждый процессор оперирует с <math>\frac{n}{k}</math> строками, в каждой из которых примерно <math>\frac{nnz}{n}</math> элементов. Параллельная сложность алгоритма - <math>O(\frac{nnz}{k})</math>


*Последовательная сложность алгоритма - <math>nnz</math>
*При этом вычислительная мощность алгоритма (как отношение числа операций к суммарному объему входных и выходных данных) – <math>O(\frac{nnz}{k}*\frac{nnz}{k})</math>.
 
При этом алгоритм умножения матрицы на вектор полностью детерминирован. Использование другого порядка выполнения ассоциативных операций в данной версии нами не рассматривается.


== Программная реализация алгоритма ==
== Программная реализация алгоритма ==

Версия от 17:08, 13 октября 2016


Умножение разреженной матрицы на вектор
Последовательный алгоритм
Последовательная сложность [math]\displaystyle{ nnz }[/math]
Объём входных данных [math]\displaystyle{ 2(nnz+n)+1 }[/math]
Объём выходных данных [math]\displaystyle{ n }[/math]
Параллельный алгоритм
Высота ярусно-параллельной формы [math]\displaystyle{ }[/math]
Ширина ярусно-параллельной формы [math]\displaystyle{ }[/math]

Авторы статьи: Третьякова Р. М. (группа 603), Буторина Е. В. (группа 603)


Свойства и структура алгоритма

Общее описание алгоритма

Разрежённая матрица — это матрица с преимущественно нулевыми элементами. В противном случае, если бо́льшая часть элементов матрицы ненулевые, матрица считается плотной. Среди специалистов нет единства в определении того, какое именно количество ненулевых элементов делает матрицу разрежённой. Разные авторы предлагают различные варианты. Огромные разрежённые матрицы часто возникают при решении таких задач, как дифференциальное уравнение в частных производных или операции с графами. При хранении и преобразовании разрежённых матриц в компьютере бывает полезно, а часто и необходимо, использовать специальные алгоритмы и структуры данных, которые учитывают разрежённую структуру матрицы. Операции и алгоритмы, применяемые для работы с обычными, плотными матрицами, применительно к большим разрежённым матрицам работают относительно медленно и требуют значительных объёмов памяти. Однако разрежённые матрицы могут быть легко сжаты путём записи только своих ненулевых элементов, что снижает требования к компьютерной памяти. Сложность операции с разреженными матрицами чаще всего определяется не их размером но числом ненулевых элементов. Далее будет показано, что умножение разреженной матрицы на плотный вектор можно произвести ровно за столько умножений сколько в матрице ненулевых элементов.

Математическое описание алгоритма

Исходные данные: разреженная матрица [math]\displaystyle{ M^{n*n} }[/math], вектор [math]\displaystyle{ x^{n*1} }[/math]

Наиболее удобным форматом для вычисления произведения матрицы на вектор является "Compressed Sparse Row" или сокращенно CSR-формат.

Рассмотрим CSR-представление разреженной матрицы: пусть число ненулевых элементов матрицы равно [math]\displaystyle{ nnz }[/math] CSR-формат представляет матрицу [math]\displaystyle{ M }[/math] в виде 3-х одномерных массивов:

массив [math]\displaystyle{ A }[/math] размера [math]\displaystyle{ nnz }[/math] содержит ненулевые значения матрицы, [math]\displaystyle{ JA }[/math] размера [math]\displaystyle{ nnz }[/math] - номера столбцов ненулевых элементов., [math]\displaystyle{ IA }[/math] размера [math]\displaystyle{ n }[/math]- содержит номер с которого начинается описание элементов строки в массивах [math]\displaystyle{ A }[/math] и [math]\displaystyle{ JA }[/math]. Этот формат позволяет производить перемножение матрицы [math]\displaystyle{ M }[/math] на вектор [math]\displaystyle{ x }[/math] за [math]\displaystyle{ O(nnz) }[/math] умножений и сложений.

Например, это разреженная матрица с 4-мя ненулевыми элементами

[math]\displaystyle{ \begin{pmatrix} 0 & 0 & 0 & 1 \\ 2 & 0 & 0 & 0 \\ 0 & 0 & 3 & 0 \\ 0 & 4 & 0 & 0 \\ \end{pmatrix} }[/math],
представляемая в формате CSR 
   A  = [ 1 2 3 4 ]
   IA = [ 0 1 2 3 4 ]
   JA = [ 3 0 2 1 ]


Вычисляемые данные: вектор [math]\displaystyle{ M*x=y }[/math]

Вычислительное ядро алгоритма

[math]\displaystyle{ y_i = \sum_{k = IA_i}^{IA_{i+1}} A_k x_{JA_k} }[/math]

Макроструктура алгоритма

Псевдокод алгоритма:

 Входные данные:
   число строк матрицы n; 
   разреженная матрица в формате CSR:
     строчные указатели IA,
     столбцовые указателиJA, 
     ненулевые элементы A;
   вектор x.
 Выходные данные: произведение матрицы на вектор y.
 read CSR n, IA, JA, A;
 read x
 for i = 1,n:
   for k = IA(i), IA(i+1)-1:
           y(i) += A(k)*x(JA(k));
 write y;

Схема реализации последовательного алгоритма

Метод можно описать следующим образом:

  1. привести матрицу [math]\displaystyle{ M }[/math] к формату CSR
  2. для [math]\displaystyle{ i }[/math] от [math]\displaystyle{ 0 }[/math] до [math]\displaystyle{ n-1 }[/math] вычислить [math]\displaystyle{ y_i }[/math] по формуле [math]\displaystyle{ y_i = \sum_{k = IA_i}^{IA_{i+1}} A_k x_{JA_k} }[/math]

Последовательная сложность алгоритма

Для вычисления матрично-векторного произведения матрицы размера [math]\displaystyle{ n*n }[/math] и вектора размера n в последовательном варианте требуется:

  • [math]\displaystyle{ nnz }[/math] сложений,
  • [math]\displaystyle{ nnz }[/math] умножений.

Информационный граф

Ресурс параллелизма алгоритма

Для параллельного умножения матрицы на вектор порядка [math]\displaystyle{ n }[/math] требуется последовательно выполнить следующие ярусы:

Входные и выходные данные алгоритма

Входными данными алгоритма являются:

  1. размер разреженной матрицы [math]\displaystyle{ n }[/math];
  2. вектор [math]\displaystyle{ AI }[/math] размерности [math]\displaystyle{ n+1 }[/math];
  3. вектор [math]\displaystyle{ AJ }[/math] размерности [math]\displaystyle{ nnz }[/math];
  4. вектор [math]\displaystyle{ A }[/math] размерности [math]\displaystyle{ nnz }[/math];
  5. вектор [math]\displaystyle{ x }[/math] размерности [math]\displaystyle{ n }[/math].

Суммарная размерность входных данных: [math]\displaystyle{ 2(nnz + n) + 1 }[/math]

Выходными данными является

  1. вектор [math]\displaystyle{ y }[/math] размерности [math]\displaystyle{ n }[/math].

Объем выходных данных: [math]\displaystyle{ n }[/math].

Свойства алгоритма

Если размерность матрицы [math]\displaystyle{ n }[/math], число ненулевых элементов [math]\displaystyle{ nnz }[/math], для вычисления используется [math]\displaystyle{ k }[/math] процессоров тогда:

  • Каждый процессор оперирует с [math]\displaystyle{ \frac{n}{k} }[/math] строками, в каждой из которых примерно [math]\displaystyle{ \frac{nnz}{n} }[/math] элементов. Параллельная сложность алгоритма - [math]\displaystyle{ O(\frac{nnz}{k}) }[/math]
  • При этом вычислительная мощность алгоритма (как отношение числа операций к суммарному объему входных и выходных данных) – [math]\displaystyle{ O(\frac{nnz}{k}*\frac{nnz}{k}) }[/math].

При этом алгоритм умножения матрицы на вектор полностью детерминирован. Использование другого порядка выполнения ассоциативных операций в данной версии нами не рассматривается.

Программная реализация алгоритма

Особенности реализации последовательного алгоритма

Локальность данных и вычислений

Возможные способы и особенности параллельной реализации алгоритма

Масштабируемость алгоритма и его реализации

Динамические характеристики и эффективность реализации алгоритма

Выводы для классов архитектур

Существующие реализации алгоритма

Последовательная реализация имеется в пакете SPARSKIT [1], Python.Scipy [2]

Параллельный алгоритм реализован в библиотеке Matlab [3], Intel MKL [4]

Литература

[1] С. Писсанецки. Технология разреженных матриц. Изд. Мир, 1988.

[2] В. В. Воеводин, Вл.В. Воеводин. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002.