Умножение подмножества матрицы на другую матрицу, используя lapack/blas

Я хочу умножить подмножество матрицы A на другую матрицу, используя dgemm или любую другую функцию lapack/blas. Я думаю, что, поскольку элементы подматрицы не могут быть смежными, я не могу использовать dgemm напрямую, не копируя подматрицу в другое пространство. Таким образом, когда эта подматрица сама по себе велика, она может оказаться очень неэффективной в той степени, в которой я думаю, что для меня было бы лучше написать код для умножения для этой конкретной проблемы на языке C. После копирования и последующего использования самого lapack/blas, может не быть эффективным вообще. Я использую Lapack / Blas в Matlab в качестве файла MEX.

Мои вопросы

1- Есть ли какая-либо функция Лапака / Бласа, которая может работать на подматрицах в умножении? 2. Если это не так, то лучше написать код для умножения напрямую или лучше скопировать подматрицу в другую матрицу и использовать dgemm?

1 ответ

Решение

На самом деле dgemm предназначен для умножения подматриц. Вам просто нужно правильно использовать начальные указатели для каждой матрицы и аргументы LDA, LDB, LDC,

C Вариант BLAS это:

void cblas_dgemm (const CBLAS_LAYOUT layout, const CBLAS_TRANSPOSE TransA, const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc);

Скажите, что у вас есть матрицы:

  • A(15x10)
  • B(10x20)
  • C(15x20)

призвание dgemm за Column Major матричное хранилище:

cblas_dgemm (CblasColMajor, CblasNoTrans, CblasNoTrans, 15, 20, 10, 1., A, 15, B, 10, 1., C, 15);

Предположим, вам нужно позвонить dgemm прохождение подматрицы:

  • As(3x2) начиная с точки (2,1) из A
  • Bs(2x5) начиная с точки (3,5) из B
  • Cs(3x5) начиная с точки (4,2) из C

N, M, K изменится на 3, 5, 2, но LDXs останется таким же, как указано выше. Затем вы должны передать правильные указатели dgemm так что они будут указывать на начало каждой подматрицы. Так как у вас есть C нумерация вы должны вычесть один из каждой координаты.

  • As отправная точка A + (1+0*15)
  • Bs отправная точка B + (2+4*10)
  • Cs отправная точка C + (3+1*15)

    cblas_dgemm (CblasColMajor, CblasNoTrans, CblasNoTrans, 3, 5, 2, 1., A+1, 15, B+42, 10, 1., C+18, 15);
    

Идея NLDA это сказать, что у меня есть матрица A(LDA,*) но я буду использовать верхнюю подматрицу As(N,*), В примерах вы не хотите использовать верхнюю подматрицу, но некоторые другие внутри A, В этом случае вы создаете новый указатель A+1 в матрицу. Сейчас As верхняя подматрица A+1,

Точно так же называя оригинал Фортрана dgemm функция от C будет

    char NoTrans = `N`;
    int N = 3;
    int M = 5;
    int K = 2;
    int LDA = 15;
    int LDB = 10;
    int LDC = 15;
    double alpha = 1.0;
    double beta = 1.0;
    dgemm (&NoTrans, &NoTrans, N, M, K, alpha, A+1, LDA, B+42, LDB, beta, C+18, LDC);
Другие вопросы по тегам