Реализация CUDA для арифметики произвольной точности

Мне нужно умножить две очень большие (~ 2000 X 2000) плотные матрицы, записи которых являются числами с произвольной точностью (я использую GMP, и точность в настоящее время установлена ​​​​на 600). Мне было интересно, есть ли какая-нибудь библиотека CUDA, поддерживающая арифметику произвольной точности? Единственная библиотека, которую я нашел, называется CAMPARY, однако в ней отсутствуют ссылки на некоторые используемые функции.

Другим решением, о котором я думал, была реализация версии алгоритма Карацубы для умножения матриц с элементами произвольной точности. Конечным этапом алгоритма будет просто умножение матриц двойных чисел, что можно очень эффективно выполнить с помощью cuBLAS. Есть ли уже аналогичная реализация?


person Luca Iliesiu    schedule 27.04.2016    source источник
comment
cump может представлять интерес   -  person Robert Crovella    schedule 27.04.2016
comment
Знаете ли вы, использует ли cump только базовый алгоритм умножения? (На первый взгляд так кажется) Кажется, что GMP предлагает значительное ускорение за счет предоставления алгоритмов с лучшей асимптотической сложностью, таких как алгоритм Карацубы и алгоритм на основе БПФ. Я думаю, учитывая точность, которую я использую, возможно, не стоит переносить вычисления на графический процессор, если я не использую один из этих более эффективных алгоритмов.   -  person Luca Iliesiu    schedule 27.04.2016


Ответы (1)


Поскольку до сих пор никто не предложил такую ​​библиотеку, давайте предположим, что ее не существует.

Вы всегда можете реализовать наивную реализацию:

  • Один поток сетки для каждой пары координат в выходной матрице.
  • Каждый поток выполняет скалярное произведение строки и столбца во входных матрицах.
  • Операции с отдельными элементами будут использовать код, взятый из GMP (надеюсь, не намного больше, чем копирование и вставка).

Но вы также можете сделать лучше, чем это - точно так же, как вы можете сделать лучше для обычного умножения матриц с плавающей запятой. Вот моя идея (вероятно, не лучшая, конечно):

Рассмотрим рабочий пример умножения матриц с использованием общих памяти в Руководстве по программированию CUDA C. Он предлагает размещать небольшие подматрицы в разделяемой памяти. Вы все еще можете сделать это, но вам нужно быть осторожным с размерами общей памяти (они маленькие...):

  • Типичный графический процессор сегодня имеет 64 КБ общей памяти, которую можно использовать на блок сетки (или больше).
  • Они принимают подматрицу 16 x 16.
  • Умножить на 2 (для двух множителей)
  • Times ceil(801/8) (при условии, что GMP-представление использует 600 бит от мантиссы, один бит для знака и 200 бит от экспоненты)
  • So 512 * 101 < 64 KB !

Это означает, что вы, вероятно, можете просто использовать код в их рабочем примере как есть, снова заменив умножение и сложение с плавающей запятой кодом из GMP.

Затем вы можете рассмотреть что-то вроде распараллеливания самого кода GMP, то есть использования нескольких потоков для совместной работы с отдельными парами чисел с точностью до 600 бит. Это, вероятно, поможет вашему шаблону чтения общей памяти. В качестве альтернативы вы можете чередовать размещение 4-байтовых последовательностей из представления ваших элементов в общей памяти для того же эффекта.

Я понимаю, что это немного волнообразно, но я почти уверен, что правильно взмахнул руками, и это будет простой вопрос кодирования.

person einpoklum    schedule 01.02.2021