LAPACK zgemm op (A) размерность

В этот ссылка из netlib указывает M как:

На входе M указывает количество строк матрицы
op (A) и матрицы C. M должно быть не меньше нуля.
Без изменений при выходе.

Так что, если я хочу использовать матрицу 3×10 в качестве A, но я хочу использовать ее сопряженную для zgemm (TRANSA = ‘C’), что я должен ввести как M? 3 или 10?

Также, когда я использовал другие подпрограммы LAPACK, я вводил двумерные матрицы как 1D, например, A [3 * 3] вместо A [3] [3], и после вызова подпрограммы я просто использовал A для матрицы. Могу ли я сделать то же самое с не квадратные матрицы? A [3 * 10] вместо A [3] [10]?

Я кодирую на C ++.

3

Решение

Соглашение об именовании / уточнение

Прежде чем дать ответ и для большей ясности, важно иметь в виду этот факт:

  • в США M — размер строки, N — размер столбца.

в то время как

  • в некоторых других местах, например в Европе, это обратное N для размера строки и M для размера столбца

Комментарии:

  • Все документы Blas / Lapack, которые вы найдете на netlib.org, используют соглашение США

  • Я (как европеец) должен признать, что конвенция США более логична, чем индексы (i, j) и (m, n), следующие за тот же алфавитный порядок

Чтобы избежать такой двусмысленности, я обычно использую:

  • I_size для размера строки а также J_size для размера столбца

B / Ответы

B.1 / гемм

void cblas_zgemm(CBLAS_LAYOUT layout,
CBLAS_TRANSPOSE opA,
CBLAS_TRANSPOSE opB,
const int M, <-------------- I_Size of op(A)
const int N, <-------------- J_Size of op(B)
const int K, <-------------- J_Size of op(A)
const void* alpha,
const void* A,
const int lda,
const void* B,
const int ldb,
const void* beta,
void* C,
const int ldc);

В глаголах если ТРАНСА = ‘Т’ Вы должны взять размеры транспонировать Матрица

Реализация для вызова cblas_zgemm может выглядеть так:

const Size_t opA_I_size = (opA == CblasNoTrans) ? A.I_size() : A.J_size();
const Size_t opA_J_size = (opA == CblasNoTrans) ? A.J_size() : A.I_size();

const Size_t opB_I_size = (opB == CblasNoTrans) ? B.I_size() : B.J_size();
const Size_t opB_J_size = (opB == CblasNoTrans) ? B.J_size() : B.I_size();

cblas_zgemm(CblasColMajor,
opA,
opB,
opA_I_size,
opB_J_size,
opA_J_size,
alpha,
A.data(),
A.ld(),
B.data(),
B.ld(),
beta,
C.data(),
C.ld());

Б.2 / Расположение памяти

Для совместимости Blas / Lapack и, в более общем случае, для обработки чисел …

никогда не используйте A [I_size] [J_size], но всегда A [I_size * J_size]

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

Чтобы быть более точным за

  • основной столбец (стиль Фортран) у вас есть: A [ld * J_size]

  • основная строка (стиль C): A [I_size * ld]

(где л.д. это ведущее измерение)

Обновления:

  • Даже если вы кодируете в C ++ Я рекомендую использовать соглашение Фортрана (колонка Major). Lapacke притворяется, что поддерживает основной режим строки, однако, под капотом, он просто копии Ваша матрица в основной макет столбца перед вызовом запрошенной подпрограммы. Так что это дополнительное средство — всего лишь иллюзия (в отношении перфораторов). Чтобы быть более точным, это Функция LAPACKE_dge_trans (). Вы можете проверить код Лапаке, чтобы увидеть, что эта функция используется почти везде, как только Layout=RowMajor (см. lapacke_dgesv_work () код например).

  • Также обратите внимание, что если вы хотите общие шаги («произвольное начальное измерение» в направлениях I и J), вы можете использовать библиотеку, например Blis вместо Блас. Настоящим преимуществом является возможность создавать произвольные 2D-виды тензоров. Этот выбор зависит от вашего приложения, я не знаю, имеете ли вы в виду манипуляцию с тензором.

B.3 / Размеры матрицы

Если ваши матрицы всегда будут такими маленькими, как 3×10 blas / lapack, это не лучший выбор (для исполнения). Рассмотрите возможность использования библиотеки как собственный или же Blaz.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]