Развлекался сегодня вечером с BLAS Level 3 через C-интерфейс. Очень сильно мучался из-за практически полного отсутствия вменяемой документации именно по C-интерфейсу, приходилось параллельно CBLAS API Reference листать ещё 3 или 4 доки, чтобы понять как же оно работает. Вобщем, под катом небольшой reference на русском:
Сначала некоторые общие сведения по naming conventions в названиях функций:
Вообще все функции CBLAS это те же функции что и в BLAS, но с префиксом вида cblas_. Дальше идёт идентификатор точности результата: S для float, D для double, C для комплексных чисел точности float и Z для комплексных чисел точности double. Записываются комплексные числа, кстати, в виде z[] = {0.5, 0.5}, а вектор из двух чисел 1+i и 2+2i будет выглядеть как {1, 1, 2, 2}.
Я буду рассматривать только функции двойной точности для работы с вещественными числами, обобщение на комплексную плоскость проблем вызвать не должно.
Собственно то, ради чего я вообще начал с BLAS разбираться это функция cblas_dtrsv, предназначенная для решения верхне- и нижне-треугольных систем уравнений вида .
Прототип этой функции выглядит вот так:
void cblas_dtrsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const double *A, const int lda, double *X, const int incX);
Начну с описания параметров:
enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102};
Указывает порядок в котором записан массив. Я использую CblasRowMajor, это стандартный порядок записи для C, к тому же IMHO он удобнее для записи. Подробнее про это почитать можно тут.
enum CBLAS_UPLO {CblasUpper=121, CblasLower=122};
Указывает, какую систему решаем — верхне-треугольную или нижне-треугольную соответственно.
enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113};
Указывает, необходимо ли перед решением системы транспонировать матрицу. CblasNoTrans: обычная матрица, CblasTrans: A — транспонированная, CblasConjTrans: A — сопряжённая.
enum CBLAS_DIAG {CblasNonUnit=131, CblasUnit=132};
Указывает на вид диагональных элементов матрицы. CblasUnit — на главной диагонали матрицы стоят единицы, CblasNonUnit — для всех остальных случаев. CblasNonUnit работает так же и для единичной диагонали, так что скорее всего применяется для оптимизации работы с матрицами, у которых на главной диагонали стоят единицы.
const int N;
Размерность матрицы B.
const double *A;
Собственно матрица A.
const int lda;
Параметр, использующийся для указания расстояния в памяти между двумя соседними элементами в одной колонке при условии что используется column-major ordering.
double *X;
Матрица свободных членов.
const int incX;
Число, указывающее offset между обрабатываемыми элементами в матрице свободных членов.
Результат эта функция пишет в X, так что если он вам необходим для дальнейшей работы, то его нужно скопировать.
Далее я кратко опишу оставшиеся функции, работающие со всеми типами матриц, опуская оптимизированные (для Эрмитовых, симметричных и т.п. матриц)
void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum 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 и B, прибавляя к ним C. Результат сохраняется в C.
void cblas_dtrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb);
Перемножает треугольную матрицу A и матрицу B размера M x N, в зависимости от значения CBLAS_SIDE:
CblasLeft:
CblasRight:
Собственно вот и всё, оставшееся — функции для специальных матриц.