Тествам функциите на Intel MKL в C тестова програма и установих, че просто не мога да направя функцията spareblas: mkl_scsrmm CSR еднобазиранаиндексираща работа. Използвам CSR с вариациите val, columns, pntrb и pntre. Оригиналните примери са поставени в:
...mkl\examples\examples_core_c\spblasc\source\cspblas_scsr.c
Това е първият код за нулево индексиране:
Пример #1
#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. Мисля, че има липса на яснота относно описанието на масив b за функцията mkl_scsrmm, поставено в справочното ръководство на MKL. Така промених b формата в този пример и той проработи (поставих позицията на елементите в този ред: `{2.0, 5.0, 1.0, 2.0}) Но направих същото за друг пример 3x3, който кодирах, и той не работи, така че Мисля, че може да е просто съвпадение. Наистина не знам какво да правя с този проблем, бих искал да разбера какво се случва тук.
Препратки:
CSR формат
https://software.intel.com/en-us/node/471374
Резервна функция Blas mkl_scsrmm
Съображения за резервен интерфейс Blas
И ето още един пример, този 3x3:
Пример #2
// 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;
}