#cuda #cublas
#cuda #cublas
Вопрос:
Я работаю с некоторыми большими данными, используя библиотеку cublas для умножения матриц. Чтобы сэкономить место в памяти, я хочу что-то вроде A=A*B
where A
и B
являются квадратными матрицами n на n, т. Е. Используют одно и то же пространство памяти для вывода и одной из входных матриц.
Хотя в некоторых старых сообщениях говорится, что это запрещено в библиотеке cublas, я фактически реализовал это с помощью cublasZgemmStridedBatched()
функции. Удивительно, но вычисление абсолютно правильное и стабильно при повторном запуске. Поэтому мне интересно, поддерживается ли перекрывающийся ввод и вывод текущей библиотекой cublas. Если да, то сколько памяти это на самом деле экономит? Я имею в виду, что интуитивно функции, по крайней мере, требуется дополнительная память для хранения промежуточных вычислений, поскольку A
ij
= A
ik
B
kj
она зависит от целого ряда A
. Это особенно экономит память для пакетных gemm?
Комментарии:
1. Я думаю, что в общем случае перекрытие ввода / вывода в CUBLAS не предусмотрено, за некоторыми исключениями, такими как
geam
. Я подозреваю, что в случае различных операций умножения матриц, в том числеgemmStridedBatched
, вы могли бы подготовить демонстрационный пример, в котором вы могли бы наблюдать сбой, возможно, с использованием матриц, которые были достаточно большими по отдельности.2. @Robert Crovella Спасибо за комментарии. Я провел дополнительные тесты, используя ‘cublasDgemm ()’. на моем графическом процессоре операция на месте выполняется правильно ровно до матрицы размером 512 на 512, и она становится неправильной для матрицы размером 513 на 513.
3. Ситуации, когда это, кажется, работает и, похоже, не работает, могут зависеть от типа графического процессора, версии CUDA и конкретной функции CUBLAS и, возможно, других переменных. Вашего тестового примера достаточно, чтобы продемонстрировать, что он не предусмотрен в целом, и поэтому я бы очень неохотно полагался на него, даже с определенными ограничениями.
Ответ №1:
Хотя в некоторых старых сообщениях говорится, что это запрещено в библиотеке cublas,
И они полностью верны (отмечая, что «старые сообщения» ссылались на стандартные вызовы GEMM, а не на пакетные реализации, о которых вы спрашиваете).
На самом деле я реализовал это с помощью
cublasZgemmStridedBatched()
функции. Удивительно, но вычисление абсолютно правильное и стабильно при повторном запуске
Это не задокументировано как безопасное, и я подозреваю, что вы, вероятно, получаете стабильные результаты только по счастливой случайности, учитывая, что небольшие матрицы, вероятно, предварительно загружены в общую память или регистры, и поэтому работает операция на месте. Если бы вы перешли к более крупным матрицам, я думаю, вы бы увидели сбои, потому что в конечном итоге был бы случай, когда один GEMM не мог быть выполнен без многократных обращений к исходной матрице после цикла записи, что привело бы к повреждению исходной матрицы.
Я бы не рекомендовал операции на месте, даже если вы обнаружите, что это работает для одного случая. Различные размеры проблем, версии библиотек и аппаратные средства могут приводить к сбоям, которые вы просто не тестировали. Выбор и связанные с ним риски зависят от вас.
Комментарии:
1. Спасибо за ваш ответ, и вы абсолютно правы. Я сделал больше тестов, используя
cublasDgemm()
. на моем графическом процессоре операция на месте выполняется правильно ровно до матрицы размером 512 на 512, и она становится неправильной для матрицы размером 513 на 513.