[英]Intel MKL SpareBlas mm CSR one-based indexing not working
我正在C測試程序中測試Intel MKL的功能,但我發現我不能做多余的事情 : mkl_scsrmm函數CSR 基於索引的工作。 我正在將CSR與val,columns,pntrb和pntre一起使用。 原始示例位於:
“...... MKL \\例子\\ examples_core_c \\ spblasc \\源\\ cspblas_scsr.c”
這是基於零的索引的第一個代碼:
#include <stdio.h>
#include "mkl_types.h"
#include "mkl_spblas.h"
int main() {
#define M 2
#define NNZ 4
MKL_INT m = M, nnz = NNZ;
float values[NNZ] = {2.0,4.0,4.0,2.0};
MKL_INT columns[NNZ] = {1,2,1,2};
MKL_INT rowIndex[M+1] = {1,3,5};
#define N 2
MKL_INT n = N;
float b[M][N] = {2.0, 1.0, 5.0, 2.0};
float c[M][N] = {0.0, 0.0, 0.0, 0.0};
float alpha = 1.0, beta = 0.0;
char transa, uplo, nonunit;
char matdescra[6];
MKL_INT i, j, is;
transa = 'N';
matdescra[0] = 'S';
matdescra[1] = 'L';
matdescra[2] = 'N';
matdescra[3] = 'F';
mkl_scsrmm(&transa, &m, &n, &m, &alpha, matdescra, values, columns, rowIndex, &(rowIndex[1]), &(b[0][0]), &n, &beta, &(c[0][0]), &n);
printf(" \n");
printf(" OUTPUT DATA FOR MKL_SCSRMM\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%7.1f", c[i][j]);
};
printf("\n");
};
return 0;
}
我得到的結果是這樣的:
從零開始的索引(正確的索引):
24.0 10.0
18.0 8.0
基於索引的索引:
8.0 10.0
18.0 24.0
盡管看起來它只改變對角線元素的位置,但對於3x3矩陣,其解決方案與右圖完全不同 。 我懷疑這可能與矩陣b的輸入格式有關。 我認為MKL參考手冊中放置的函數mkl_scsrmm對數組b的描述不夠清楚。 因此,在本示例中,我更改了b格式,並且它起作用了(我按以下順序放置元素位置:`{2.0、5.0、1.0、2.0})但是對於我編寫的另一個3x3示例,我也做了相同的操作,但是這樣不起作用我認為這可能只是一個巧合。 我真的不知道該怎么辦,我想了解這里發生的情況。
參考文獻:
CSR格式
https://software.intel.com/en-us/node/471374
備用Blas mkl_scsrmm函數
備用Blas接口注意事項
這是另一個示例,即3x3:
// matrix A
//
// 2 4 3
// 4 2 1
// 3 1 6
//
// matrix B
//
// 2 1 3
// 4 5 6
// 7 8 9
//
// ZERO-BASED INDEXING
//
// a = {2 4 3 4 2 1 3 1 6}
// columns= {0 1 2 0 1 2 0 1 2}
// idexRow = {0 3 6 9}
//
// b = {2 1 3 4 5 6 7 8 9} (row order array)
//
// We print the array in row-major order
//
// ONE-BASED INDEXING
//
// a = {2 4 3 4 2 1 3 1 6}
// columns={1 2 3 1 2 3 1 2 3}
// indexRow = {0 3 6 9}
//
// b = {2 4 7 1 5 8 3 6 9} (column order array)
//
// We print the array in column-major order (because the resoult is in column major order, ie transposed)
//
//
//
#include <stdio.h>
#include "mkl_types.h"
#include "mkl_spblas.h"
int main()
{
#define M 3
#define NNZ 9
#define N 3
MKL_INT m = M, nnz = NNZ, n=N;
float a[NNZ] = {2.0,4.0,3.0,4.0,2.0,1.0,3.0,1.0,6.0};
MKL_INT columns[NNZ] = {0,1,2,0,1,2,0,1,2};
MKL_INT rowIndex[M+1] = {0,3,6,9};
float b[M][N] = {2.0, 1.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
float c[M][N] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
float alpha = 1.0, beta = 0.0;
MKL_INT i, j;
char transa;
char matdescra[6];
float a1[NNZ] = {2.0,4.0,3.0,4.0,2.0,1.0,3.0,1.0,6.0};
MKL_INT columns1[NNZ] = {1,2,3,1,2,3,1,2,3};
MKL_INT rowIndex1[M+1] = {1,4,7,10};
float b1[M][N] = {2.0, 4.0, 7.0, 1.0, 5.0, 8.0, 3.0, 6.0, 9.0};
float c1[M][N] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
//********************************
//ZERO-BASED INDEXING
//********************************
transa = 'n';
matdescra[0] = 's';
matdescra[1] = 'l';
matdescra[2] = 'n';
matdescra[3] = 'c';
mkl_scsrmm(&transa, &m, &n, &m, &alpha, matdescra, a, columns, rowIndex, &(rowIndex[1]), &(b[0][0]), &n, &beta, &(c[0][0]), &n);
printf(" \n");
printf(" Right Solution: ZERO-BASED: C \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++) {
printf("%7.1f", c[i][j]);
};
printf("\n");
};
printf(" \n");
printf(" ZERO-BASED: C' \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%7.1f", c[j][i]);
};
printf("\n");
};
//********************************
//ONE-BASED INDEXING
//********************************
matdescra[3] = 'f';
mkl_scsrmm(&transa, &m, &n, &m, &alpha, matdescra, a1, columns1, rowIndex1, &(rowIndex1[1]), &(b1[0][0]), &n, &beta, &(c1[0][0]), &n);
printf(" \n");
printf(" ONE-BASED: C \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%7.1f", c1[i][j]);
};
printf("\n");
};
printf(" \n");
printf(" ONE-BASED: C' \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%7.1f", c1[j][i]);
};
printf("\n");
};
return 0;
}
我在英特爾論壇上問了同樣的問題,並且在那里得到了一些幫助,並找到了解決問題的方法。 達成的協議是,當使用基於零的索引從C接口調用例程時,可以按照行優先順序( 本機C數組存儲 )發送存儲在數組中的矩陣,而使用基於一的索引調用例程時,以列優先順序存儲矩陣。 這改變了矩陣B和C需要存儲的方式以及結果存儲的方式。 對於矩陣A,它僅更改索引(從0到1)。 從英特爾的文檔中,您可能會認為C接口對於兩種類型的索引都始終接受行優先的順序。
請注意,它是,在一般情況下, 列優先順序是不 一樣的存儲行主排序的轉置矩陣 (它是相同的,如果矩陣是正方形)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.