Developer Reference for Intel® oneAPI Math Kernel Library for C

ID 766684
Date 11/07/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

BLAS Code Examples

Example. Using BLAS Level 1 Function

The following example illustrates a call to the BLAS Level 1 function sdot. This function performs a vector-vector operation of computing a scalar product of two single-precision real vectors x and y.

Parameters

 

n

Specifies the number of elements in vectors x and y.

incx

Specifies the increment for the elements of x.

incy

Specifies the increment for the elements of y.
#include <stdio.h>
#include <stdlib.h>

#include "mkl_example.h"

int main()
{
      MKL_INT  n, incx, incy, i;
      float   *x, *y;
      float    res;
      MKL_INT  len_x, len_y;


      n = 5;
      incx = 2;
      incy = 1;

      len_x = 1+(n-1)*abs(incx);
      len_y = 1+(n-1)*abs(incy);
      x    = (float *)calloc( len_x, sizeof( float ) );
      y    = (float *)calloc( len_y, sizeof( float ) );
      if( x == NULL || y == NULL ) {
          printf( "\n Can't allocate memory for arrays\n");
          return 1;
      }

      for (i = 0; i < n; i++) {
          x[i*abs(incx)] = 2.0;
          y[i*abs(incy)] = 1.0;
      }

      res = cblas_sdot(n, x, incx, y, incy);

      printf("\n       SDOT = %7.3f", res);

      free(x);
      free(y);

      return 0;
}

As a result of this program execution, the following line is printed:

SDOT = 10.000

Example. Using BLAS Level 1 Routine

The following example illustrates a call to the BLAS Level 1 routine scopy. This routine performs a vector-vector operation of copying a single-precision real vector x to a vector y.

Parameters

 

n

Specifies the number of elements in vectors x and y.

incx

Specifies the increment for the elements of x.

incy

Specifies the increment for the elements of y.
#include <stdio.h>
#include <stdlib.h>

#include "mkl_example.h"

int main()
{
      MKL_INT  n, incx, incy, i;
      float   *x, *y;
      MKL_INT  len_x, len_y;
      n = 3;
      incx = 3;
      incy = 1;


      len_x = 10;
      len_y = 10;
      x    = (float *)calloc( len_x, sizeof( float ) );
      y    = (float *)calloc( len_y, sizeof( float ) );
      if( x == NULL || y == NULL ) {
          printf( "\n Can't allocate memory for arrays\n");
          return 1;
      }
      for (i = 0; i < 10; i++) {
          x[i] = i + 1;
      }

      cblas_scopy(n, x, incx, y, incy);

/*       Print output data                                     */

      printf("\n\n     OUTPUT DATA");
      PrintVectorS(FULLPRINT, n, y, incy, "Y");

      free(x);
      free(y);
      return 0;
}

As a result of this program execution, the following line is printed:

Y = 1.00000 4.00000 7.00000

Example. Using BLAS Level 2 Routine

The following example illustrates a call to the BLAS Level 2 routine sger. This routine performs a matrix-vector operation

a :=  alpha*x*y' + a.

Parameters

 

alpha

Specifies a scalar alpha.

x

m-element vector.

y

n-element vector.

a

m-by-n matrix.
#include <stdio.h>
#include <stdlib.h>

#include "mkl_example.h"

int main()
{
      MKL_INT         m, n, lda, incx, incy, i, j;
      MKL_INT         rmaxa, cmaxa;
      float           alpha;
      float          *a, *x, *y;
      CBLAS_LAYOUT    layout;
      MKL_INT         len_x, len_y;

      m = 2;
      n = 3;
      lda = 5;
      incx = 2;
      incy = 1;
      alpha = 0.5;
						layout = CblasRowMajor;

      len_x = 10;
      len_y = 10;
      rmaxa = m + 1;
      cmaxa = n;
      a = (float *)calloc( rmaxa*cmaxa, sizeof(float) );
      x = (float *)calloc( len_x, sizeof(float) );
      y = (float *)calloc( len_y, sizeof(float) );
      if( a == NULL || x == NULL || y == NULL ) {
          printf( "\n Can't allocate memory for arrays\n");
          return 1;
      }
      if( layout == CblasRowMajor )
         lda=cmaxa;
      else
         lda=rmaxa;

      for (i = 0; i < 10; i++) {
          x[i] = 1.0;
          y[i] = 1.0;
      }
      
      for (i = 0; i < m; i++) {
          for (j = 0; j < n; j++) {
              a[i + j*lda] = j + 1;
          }
      }

      cblas_sger(layout, m, n, alpha, x, incx, y, incy, a, lda);

      PrintArrayS(&layout, FULLPRINT, GENERAL_MATRIX, &m, &n, a, &lda, "A");

      free(a);
      free(x);
      free(y);

      return 0;
}

As a result of this program execution, matrix a is printed as follows:

Matrix A:

1.50000 2.50000 3.50000

1.50000 2.50000 3.50000

Example. Using BLAS Level 3 Routine

The following example illustrates a call to the BLAS Level 3 routine ssymm. This routine performs a matrix-matrix operation

c :=  alpha*a*b' + beta*c.

Parameters

 

alpha

Specifies a scalar alpha.

beta

Specifies a scalar beta.

a

Symmetric matrix

b

m-by-n matrix

c

m-by-n matrix
#include <stdio.h>
#include <stdlib.h>

#include "mkl_example.h"

int main(int argc, char *argv[])
{
      MKL_INT         m, n, i, j;
      MKL_INT         lda, ldb, ldc;
      MKL_INT         rmaxa, cmaxa, rmaxb, cmaxb, rmaxc, cmaxc;
      float           alpha, beta;
      float          *a, *b, *c;
      CBLAS_LAYOUT    layout;
      CBLAS_SIDE      side;
      CBLAS_UPLO      uplo;
      MKL_INT         ma, na, typeA;
      uplo = 'u';
      side = 'l';
      layout = CblasRowMajor;
      m = 3;
      n = 2;
      lda = 3;
      ldb = 3;
      ldc = 3;
      alpha = 0.5;
      beta = 2.0;

      if( side == CblasLeft ) {
          rmaxa = m + 1;
          cmaxa = m;
          ma    = m;
          na    = m;
      } else {
          rmaxa = n + 1;
          cmaxa = n;
          ma    = n;
          na    = n;
      }
      rmaxb = m + 1;
      cmaxb = n;
      rmaxc = m + 1;
      cmaxc = n;
      a = (float *)calloc( rmaxa*cmaxa, sizeof(float) );
      b = (float *)calloc( rmaxb*cmaxb, sizeof(float) );
      c = (float *)calloc( rmaxc*cmaxc, sizeof(float) );
      if ( a == NULL || b == NULL || c == NULL ) {
           printf("\n Can't allocate memory arrays");
           return 1;
      }
      if( layout == CblasRowMajor ) {
         lda=cmaxa;
         ldb=cmaxb;
         ldc=cmaxc;
      } else {
         lda=rmaxa;
         ldb=rmaxb;
         ldc=rmaxc;
      }
      if (uplo == CblasUpper) typeA = UPPER_MATRIX;
      else                    typeA = LOWER_MATRIX;
      for (i = 0; i < m; i++) {
         for (j = 0; j < m; j++) {
            a[i + j*lda] = 1.0;
         }
      }
      for (i = 0; i < m; i++) {
         for (j = 0; j < n; j++) {
            c[i + j*ldc] = 1.0;
            b[i + j*ldb] = 2.0;
         }
      }

      cblas_ssymm(layout, side, uplo, m, n, alpha, a, lda,
                  b, ldb, beta, c, ldc);

      printf("\n\n     OUTPUT DATA");
      PrintArrayS(&layout, FULLPRINT, GENERAL_MATRIX, &m, &n, c, &ldc, "C");

      free(a);
      free(b);
      free(c);

      return 0;
}

As a result of this program execution, matrix c is printed as follows:

Matrix C:

5.00000 5.00000

5.00000 5.00000

5.00000 5.00000

The following example illustrates a call from a C program to the Fortran version of the complex BLAS Level 1 function zdotc(). This function computes the dot product of two double-precision complex vectors.

Example. Calling a Complex BLAS Level 1 Function from C

In this example, the complex dot product is returned in the structure c.

#include <cstdio>
#include "mkl_blas.h"
#define N 5
void main()
{
  int n, inca = 1, incb = 1, i;
  MKL_Complex16 a[N], b[N], c;
  void zdotc();
  n = N;
  for( i = 0; i < n; i++ ){
    a[i].real = (double)i; a[i].imag = (double)i * 2.0;
    b[i].real = (double)(n - i); b[i].imag = (double)i * 2.0;
  }
  zdotc( &c, &n, a, &inca, b, &incb );
  printf( "The complex dot product is: ( %6.2f, %6.2f )\n", c.real, c.imag );
}
NOTE:

Instead of calling BLAS directly from C programs, you might wish to use the C interface to the Basic Linear Algebra Subprograms (CBLAS) implemented in Intel® oneAPI Math Kernel Library (oneMKL). SeeC Interface Conventions for more information.