Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.

dgemm routine works incorrectly

vich_ka
Beginner
542 Views

Hi! Please, help me:) I don't know what's wrong... maybe my hands... maybe my programm:)))

So, elementary code how i used dgemm:

static double A[2][3],B[3][2],C[2][2];

int main(){
int i,j;

for(i=0;i<2;i++){
for(j=0;j<3;j++){
A=(double)(j+1);
}
}
for(i=0;i<3;i++){
for(j=0;j<2;j++){
B=(double)(i+1);
}
}
dgemm_64('N','N',2,2,3,1.0,&A[0][0],2,&B[0][0],3,0.0,&C[0][0],2);
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%le ",C);
}
}
}

Answer = [8 9;17 16], but it must be [14 14;14 14].

I don't know what to do:(

0 Kudos
9 Replies
Evgueni_P_Intel
Employee
542 Views
Quoting - vich_ka

Hi! Please, help me:) I don't know what's wrong... maybe my hands... maybe my programm:)))

So, elementary code how i used dgemm:

//begin

static double A[1][3],B[3][1],C[1][1];
int main(){
int i,j;
for(i=0;i<2;i++){
A[0]=(double) (i+1);
}

for(i=0;i<3;i++){
B[0]=(double) (i+1);
}
dgemm('N','N',1,1,3,1.0,&A[0][0],1,&B[0][0],3,0.0,&C[0][0],1);
printf("%le ",C[0][0]);
}

//end

Answer=5. But "in my opinion" it should be 14!

I don't know what to do:(


Most likely, increment 3 is incorrect for B.
The correct incrementwould be1.
0 Kudos
barragan_villanueva_
Valued Contributor I
542 Views

Hi,

In MKL dgemm has FORTRAN-like interface,and all arguments should be passed by reference.
So, correct example is to be as follows:

#include
#include

static double A[1][3],B[3][1],C[1][1];
int main(){
int i,j;
int one=1;
int three=3;
double a=1.0;
double b=0.0;

for(i=0;i<3;i++){
A[0]=(double) (i+1);
}

for(i=0;i<3;i++){
B[0]=(double) (i+1);
}
dgemm("N","N",&one,&one,&three,&a,&A[0][0],&one,&B[0][0],&three,&b,&C[0][0],&one);
printf("%le ",C[0][0]);
}

which gives 1.400000e+01

Thanks
-- Victor

0 Kudos
vich_ka
Beginner
542 Views

Most likely, increment 3 is incorrect for B.
The correct incrementwould be1.
I don't understand why it should be 1... but i tried to do it and have an error...
0 Kudos
vich_ka
Beginner
542 Views

Hi,

In MKL dgemm has FORTRAN-like interface,and all arguments should be passed by reference.
So, correct example is to be as follows:

#include
#include

static double A[1][3],B[3][1],C[1][1];
int main(){
int i,j;
int one=1;
int three=3;
double a=1.0;
double b=0.0;

for(i=0;i<3;i++){
A[0]=(double) (i+1);
}

for(i=0;i<3;i++){
B[0]=(double) (i+1);
}
dgemm("N","N",&one,&one,&three,&a,&A[0][0],&one,&B[0][0],&three,&b,&C[0][0],&one);
printf("%le ",C[0][0]);
}

which gives 1.400000e+01

Thanks
-- Victor

thanks for your answer.

In my code was silly error

for(i=0;i<2;i++){
A[0]=(double) (i+1);
}

instead of

for(i=0;i<3;i++){
A[0]=(double) (i+1);
}

you've seen it. so, i set it right and now i have right answer = 14.

but my general problem isn't solved. i've corrected the first topic. please look it over again. there is new example, which incorrect.

i use "sunperf.h" library, which include "mkl_blas.h". i tried to pass arguments by reference, but have an error.

0 Kudos
Evgueni_P_Intel
Employee
542 Views

vich_ka, yes i was wrong about the increment.
0 Kudos
barragan_villanueva_
Valued Contributor I
542 Views
Hi,

Your new code corresponds to the following operation:

A= {{1, 2, 3}, {1, 2, 3}}

B= {{1, 1}, {2, 2}, {3, 3}}

Therefore:

|1 3 2| |1 2| |8 17|
* |1 3| =
|2 1 3| |2 3| |9 16|

not as you want

|1 2 3||1 1| |14 14|
* |2 2| =
|1 2 3||3 3| |14 14|

So, the problem is in data layout

Thanks
-- Victor
0 Kudos
vich_ka
Beginner
542 Views
Hi,

Your code corresponds to the following operation:

A= {{1, 2, 3}, {1, 2, 3}}

B= {{1, 1}, {2, 2}, {3, 3}}

Therefore:

|1 3 2| |1 2| |8 17|
* |1 3| =
|2 1 3| |2 3| |9 16|

not as you want

|1 2 3||1 1| |14 14|
* |2 2| =
|1 2 3||3 3| |14 14|

So, the problem is in data layout

Thanks
-- Victor

Thanks a lot, we don't know this feature. I thought that if i write "A[2][3]" it means that A is two-dimensional array instead of string:) Even in the help i read: " A (input) DOUBLE PRECISION array of DIMENSION ( LDA, ka )".

You really save us:) Thanks!

0 Kudos
Vladimir_Koldakov__I
New Contributor III
542 Views

Hi,

It's really the MKL dgemm assumes column-major matrix ordering so the input data should be reorganized.

There is one more option: using cblas_dgemm interface that allows both column- and row-major matrix ordering:

void cblas_dgemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA,

const CBLAS_TRANSPOSE TransB, const MKL_INT M, const MKL_INT N,

const MKL_INT K, const double alpha, const double *A,

const MKL_INT lda, const double *B, const MKL_INT ldb,

const double beta, double *C, const MKL_INT ldc);

Thanks,

Vladimir

0 Kudos
barragan_villanueva_
Valued Contributor I
542 Views
Quoting - vich_ka

i use "sunperf.h" library, which include "mkl_blas.h". i tried to pass arguments by reference, but have an error.


It looks like using "sunperf.h" calls directly MKL FORTRAN dgemm not cblas_dgemm where data layout can be C or FORTRAN.
0 Kudos
Reply