Пример использования процедуры xGEMM из библиотеки BLAS в программе на Си

 

BLAS (Basic Linear Algebra Subroutines) - библиотека базовых подпрограмм линейной алгебры. Это набор подпрограмм для выполнения базовых операций над векторами и матрицами. Библиотека BLAS имеет интерфейсы к языкам Fortran и C. Ниже приведен пример использования процедуры xGEMM из библиотека BLAS в программе на C.

 

Процедура xGEMM вычисляет следующее выражение: С = αAB + βC

где:      A - матрица M*K

            B - матрица K*N

            C - матрица M*N

            α, β - коэффициенты.

 

Первая буква в названии функции определяет тип данных элементов матрицы:

            S - вещественный с одинарной точностью (например, SGEMM),

            D - вещественный с двойной точностью (например, DGEMM),

            С - комплексный с одинарной точностью (например, CGEMM),

            Z - комплексный с двойной точностью (например, ZGEMM).

 

Прототип функции SGEMM в интерфейсе языка C выглядит следующим образом:

void cblas_sgemm(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 float alpha, const float *A,

   const int lda, const float *B, const int ldb,

   const float beta, float *C, const int ldc);

где:      Order - определяет порядок следования элементов:

                        CblasRowMajor - матрицы хранятся по строкам (стандартно в C),

                        CblasColMajor - матрицы хранятся по столбцам;

            TransA, TransB - определяет предварительные операции над матрицами A и B:

                        CblasNoTrans - ничего не делать,

                        CblasTrans - транспонировать,

                        CblasConjTrans - вычислить сопряженную матрицу;

            M, N, K          - размеры матриц;

            alpha, beta       - коэффициенты;

lda, ldb, ldc      - число элементов в ведущей размерности матрицы (строке или столбце). Для массивов языка Си - число элементов в строке:

                        lda = K

                        ldb = N

                        ldc = N

 

Для использования процедур из библиотеки BLAS, необходимо, чтобы массивы в памяти хранились одним непрерывным блоком. Например, массив A из следующего примера нельзя передавать в качестве параметра в BLAS-процедуру:

     float **A=(float**)malloc(M*sizeof(float*));

     for (i=0;i<M;i++) A[i]=(float*)malloc(K*sizeof(float));

В нем не гарантировано, что строки будут следовать одна за другой. Следующий массив B использовать можно:

float **B=(float**)malloc(M*sizeof(float*));

float *B1=(float*)malloc(M*K*sizeof(float))

for (i=0;i<M;i++) B[i]=&B1[i*K];

 

 

Пример программы умножения двух матриц с использованием BLAS:

#include<stdio.h>

#include<cblas.h>  // заголовочный файл C-интерфейса библиотеки BLAS

#define M 300

#define N 400

#define K 500

int main()

{ int i,j;

  float A[M*K],   // массив расположен в памяти одним непрерывным блоком

        B[K][N],  // этот тоже

        *C;       // и этот тоже будет непрерывным

  C=(float*)malloc(M*N*sizeof(float)); // ну вот, непрерывный ;)

  for (i=0;i<M;i++)     // инициализируем массив A

    for (j=0;j<K;j++)

      A[i*K+j]=3*j+2*i;

  for (i=0;i<K;i++)     // инициализируем массив B

    for (j=0;j<N;j++)

      B[i][j]=5*i+j;

  for (i=0;i<M*N;i++) C[i]=5; // инициализируем массив C (зачем?)

  // перемножаем!!!

  // нам нужно C=AB, поэтому сделаем beta=0

  cblas_sgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,

              M,N,K,1.0,A,K,&B[0][0],N,0.0,C,N);

  for (i=0;i<M;i++) // выводим результат на экран (наверно не влезет: 300*400)

  { for (j=0;j<N;j++) printf("%.2f ",C[i*N+j]);

    printf("\n");

  }

  free(C);

  return 0;

}

 

Библиотеку ATLAS (реализацию BLAS) для ccfit можно взять отсюда: atlas3.6.0_Linux_P4SSE2.tgz. Файл можно скачать программой wget и распаковать в домашний каталог (появится каталог Linux_P4SSE2).

При компиляции программы необходимо будет указать пути к каталогам include и lib и прилинковать необходимые библиотеки libcblas.a и libatlas.a

 

Пример команды компиляции:

gcc -I $HOME/Linux_P4SSE2/include -L $HOME/Linux_P4SSE2/lib -O3 prog.c -lcblas -latlas