Векторное произведение с разреженной матрицей на нескольких графических процессорах

Мне было интересно, каков самый быстрый способ вычисления разреженного произведения матрица-вектор y = Ax в CUDA на нескольких (скажем, n) графических процессорах.

Мой наивный подход заключался в том, чтобы разделить вектор x и y на n фрагментов, по 1 фрагменту на каждом графическом процессоре. Затем также разделите матрицу A на меньшие n ^ 2 блоков A_ij и вычислите

y_i = \sum_j A_{i,j} x_j, // GPU j stores A_{i,j} and x_j, result is copied 
                          // to and summed up on GPU i 

на разных графических процессорах j = 1..n с, скажем, cuSPARSE. Это сработает? С унифицированной архитектурой памяти, в принципе, все графические процессоры должны иметь доступ к глобальной памяти.

Будет ли передача памяти между графическими процессорами невероятно медленной? Я не ожидаю большого ускорения, но мне было интересно, будет ли оно медленнее, чем умножение матрицы на вектор на одном графическом процессоре.


person yon    schedule 14.09.2015    source источник
comment
Я не думаю, что есть общий ответ на этот вопрос, он слишком обширен. Было проведено множество исследований векторного произведения разреженных матриц для систем с распределенной памятью, включая графические процессоры. Лучше прочитать кое-что из этого, чем задавать подобный вопрос здесь, в Stack Overflow   -  person talonmies    schedule 14.09.2015
comment
Ты прав. Я предполагаю, что то, что я искал, - это дешевая / простая реализация (повторное использование вызовов cuSPARSE), которая нормально работает на нескольких графических процессорах.   -  person yon    schedule 14.09.2015


Ответы (1)


Я бы предложил другой подход. Не разбивайте вектор x на куски. Перенести x на все графические процессоры.

Разбейте матрицу A по строкам. Так, например, если A имеет 9 строк, а у вас 3 графических процессора, то перенесите строки 1-3 из A на первый графический процессор, 4-6 из A на второй графический процессор и 7-9 из A на третий графический процессор. .

Затем вычислите 3 отдельные части y на 3 графических процессорах:

y[1-3] = A[1-3]*x
y[4-6] = A[4-6]*x
y[7-9] = A[7-9]*x

Каждую из этих трех операций можно выполнить с помощью cusparse<T>csrmv < / a>, например (или CUB теперь также имеет подпрограмму spmv).

Повторная сборка вектора y должна быть тривиальной (конкатенация). Нет необходимости в передаче данных между GPU во время вычислений, только при передаче результатов (y).

Возможной «оптимизацией» было бы разделение A на основе «работы», а не наивно по строкам. Но польза от этого будет зависеть от структуры A, поэтому потребуется анализ. Упрощенный подход к этой оптимизации может заключаться в том, чтобы просто разбить A на основе (приблизительно) выравнивания количества элементов NZ в каждом фрагменте.

person Robert Crovella    schedule 14.09.2015
comment
Я бы подумал, что разложение графа для распределения матрицы было бы еще одним стандартным подходом. - person talonmies; 14.09.2015