Перекрывающиеся входные и выходные данные для функций cublas

#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.