Intel MKL SpareBlas mm CSR базирано индексиране не работи

Тествам функциите на 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

https://software.intel.com/sites/products/documentation/doclib/iss/2013/mkl/mklman/hh_goto.htm#GUID-78C55D9B-86FF-4A9F-B5D5-D2F61B9314FC.htm

Съображения за резервен интерфейс Blas

https://software.intel.com/sites/products/documentation/doclib/iss/2013/mkl/mklman/hh_goto.htm#GUID-34C8DB79-0139-46E0-8B53-99F3BEE7B2D4.htm

И ето още един пример, този 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;
}

person Adrian    schedule 23.10.2014    source източник


Отговори (1)


Зададох същия въпрос във форума на Intel и получих малко помощ там и стигнах до решението на проблема. Сделката беше, че когато извиквате рутината от C интерфейс с базирано на нула индексиране, можете да изпратите матрицата, съхранена в масив, следвайки реда главен ред (роден C съхранение на масив), и когато извикате рутината с базирано на едно индексиране, трябва да съхраните матрицата в ред на главна колона. Това променя начина, по който матриците B и C трябва да бъдат съхранени и начина, по който резултатът ще бъде съхранен. За матрицата A се променя само индексирането (от 0 на 1). От документацията на Intel може да си помислите, че C интерфейсът винаги приема подреждането по главния ред и за двата вида индексиране.

Забележете, че като цяло подреждането на главната колона не е същото като съхраняването на транспонираната матрица в подреждането на главния ред< /strong> (същото е, ако матриците са квадратни).

person Adrian    schedule 26.10.2014
comment
Благодаря ви много, че публикувахте и също така отговорихте на собствения си въпрос. Вие ми помогнахте много, останах безуспешно, опитвайки се да запаметя основно колони за няколко часа, докато четях документацията. Знаете ли дали това е посочено някъде в документацията на MKL? - person fcdimitr; 15.11.2017