繁体   English   中英

使用MKL稀疏矩阵向量乘法

[英]using MKL sparse matrix vector multiply

有没有人有使用MKL稀疏矩阵向量乘法例程的简单C ++代码示例? 我需要使用“ mkl_zcsrsymv”将复杂的对称矩阵(存储在下部三角形中)与复杂的矢量相乘,但是我找不到关于此的单个说明性示例。 无法为复杂情况编译我的代码。

阅读英特尔主页上有关mkl_zcsrsymv的文档。 此处对称应按字面理解! (这并不意味着厄米)

使用icpc -mkl test.c进行编译,以提供最大的便利。

#include <stdio.h>
#include "mkl_spblas.h"

int main()
{
  /* Matrix in CRS format
   *
   * { {  0,  0,  i } 
   *   {  0, -1,  2 } 
   *   {  i,  2,  0 } } 
   */
  int m = 3;
  MKL_Complex16 a[] = { {0,1}, {-1,0}, {2,0}, {0,1}, {2,0} };
  int ia[] = { 0, 1, 3, 5 };
  int ja[] = { 2, 1, 2, 0, 1 };

  MKL_Complex16 x[] = { {1,0}, {2,0}, {3,0} };
  MKL_Complex16 y[] = { {0,0}, {0,0}, {0,0} };

  char uplo = 'L';
  // Use MKL to compute
  // y = A*x
  mkl_cspblas_zcsrsymv(&uplo, &m, a, ia, ja, x, y);

  printf("y = { (%g,%g), (%g,%g), (%g,%g) }\n",
         y[0].real, y[0].imag,
         y[1].real, y[1].imag,
         y[2].real, y[2].imag
    );
}

输出为y = { (0,3), (4,0), (4,1) } WolframAlpha上检查。


这也是mkl_dcsrmv的示例。

#include <stdio.h>
#include "mkl_spblas.h"

int main()
{
  /* Matrix in CRS format
   *
   * { { 0,  0,  1 } 
   *   { 0, -1,  2 } 
   *   { 1,  0,  0 } } 
   */
  int m = 3;
  int k = 3;
  double val[] = { 1, -1, 2, 1 };
  int indx[]   = { 2, 1, 2, 0 };
  int pntrb[]  = { 0, 1, 3 };
  int pntre[]  = { 1, 3, 4 };

  double x[] = { 1, 2, 3 };
  double y[] = { 0, 0, 0 };

  double alpha = 1;
  double beta  = 0;
  char transa = 'N';
  char matdescra[] = {
    'G', // type of matrix
    ' ', // triangular indicator (ignored in multiplication)
    ' ', // diagonal indicator (ignored in multiplication)
    'C'  // type of indexing
  };

  // Use MKL to compute
  // y = alpha*A*x + beta*y
  mkl_dcsrmv(&transa, &m, &k, &alpha, matdescra, val, indx, pntrb, pntre, x, &beta, y);

  printf("y = { %g, %g, %g }\n", y[0], y[1], y[2]);
}

输出为y = { 3, 4, 1 } WolframAlpha上检查。


在玩这个游戏时,我发现它与Armadillo直接兼容。 这使得在C ++中使用非常方便。 在这里,我首先使用犰狳生成一个随机对称矩阵,并将其转换为稀疏矩阵。 我将此乘以随机向量。 最后,我将结果与Armadillo的稀疏矩阵矢量积进行了比较。 精度差异很大。

#include <iostream>
#include <armadillo>
#define MKL_Complex16 arma::cx_double
#include "mkl_spblas.h"

int main()
{
  /* Matrix in CRS format
   *
   * { {  0,  0,  i } 
   *   {  0, -1,  2 } 
   *   {  i,  2,  0 } } 
   */
  int dim = 1000;
  arma::sp_cx_mat a(arma::randu<arma::cx_mat>(dim,dim));
  a += a.st();
  arma::cx_vec x = arma::randu<arma::cx_vec>(dim);
  arma::cx_vec y(dim);

  char uplo = 'L';
  // Use MKL to compute
  // y = A*x
  mkl_cspblas_zcsrsymv(&uplo, &dim,
                       a.values, (int*)a.col_ptrs, (int*)a.row_indices,
                       x.memptr(), y.memptr());

  std::cout << std::boolalpha
            << arma::approx_equal(y, a*x, "absdiff", 1e-10)
            << '\n';
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM