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

dgemm incorrect result

ado
Beginner
872 Views

I used randomly generated matrix to test my program and found some led to incorrect results from dgemm.

If I reduce the precision based on the printf display of the matrix, the result became correct again. So I had to save the generated matrix to a binary file so I can repeat the result. I attached the binary file as matrix3.cpp because I need to use the required extension.

The output is as follows and you can see "out" is incorrect.

Could you run the code and let me know what went wrong? Thanks.

 A=[
 7064610704830808.00000000 -2571117317297868.50000000 371407000938997.87500000
 6397257092471370.00000000 -2328238480630291.00000000 336322292936225.12500000
 -29483308061538568.00000000 10730250695401230.00000000 -1550022709306368.50000000
 -14929918819165514.00000000 5433643044981792.00000000 -784908978650044.00000000
]

 B=[
 -0.20072837 -0.01530215
 -0.57723645 -0.10924951
 -0.17790418 -0.46522968
]

 Out
 -2.00000000 -0.53125000
 0.27343750 1.50000000
 0.81250000 1.12500000
 -0.26562500 -2.68750000
]

 

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <mkl.h>

using namespace std;

void print_matrix( char* desc, MKL_INT m, MKL_INT n, double* a, MKL_INT lda );

int main()
{
		int m=4, n=3,k=2;                                
        double * A= new double [m*n];
        double * B= new double [n*k];                                                      
        double * out= new double [m*k];

		ifstream infile;
		infile.open("matrix3.cpp", ios::binary | ios::in);
        infile.read((char *)&A[0], m*n*sizeof(double));
        infile.read((char *)&B[0], n*k*sizeof(double));
        infile.close();

		cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 
                m, k, n, 1.0, A, n, B, k, 0.0, out, k);

		print_matrix("A=[",m,n,A,n);  
        print_matrix("B=[ ",n,k,B,k);
        print_matrix("Out",m,k,out,k);       

		delete[] A;
		delete[] B;
		delete[] out;
		return 0;

}

void print_matrix( char* desc, MKL_INT m, MKL_INT n, double* a, MKL_INT lda ) {
        MKL_INT i, j;
        printf( "\n %s\n", desc );
        for( i = 0; i < m; i++ ) {
                for( j = 0; j < n; j++ ) printf( " %6.8f", a[i*lda+j] );
                printf( "\n" );
        }
                printf( "]\n" );
}

 

0 Kudos
6 Replies
Zhen_Z_Intel
Employee
872 Views

Hi arth,

The problem is caused by file read, if you set value to A & B in code, the output should be like below:

dgemm.png

You may try following code to save double data in txt with UTF-8, the output should be correct.

std::ifstream fin("matrix3.txt");
for(int i=0;i<m*n;i++)
     fin>>A;
for(int i=0;i<n*k;i++)
     fin>>B;
fin.close();

Best regards,
Fiona

0 Kudos
ado
Beginner
872 Views

Thanks for checking on this.

I copied your code but it did not read anything (all 0.0's).

Actually, the original problem had nothing to do with reading a data file. I generated the matrix with code. The reason I did not save the data into a txt file is exactly due to the problem I saw. Basically, to regenerate the problem you need the original binary representation of the numbers. If you save it to a txt file, I guess you need to set precision, which will be different from the original full 8 bytes number.

I guess I also do not quite understand what did you mean that it was caused by reading the file? I printed the numbers that was read from the file and the terminal output seemed OK? Again, originally it had nothing to do with reading from a file. The numbers stored in the file was what I generated inside the code by the mkl random generator.

Your code is for reading the data file, right? Do I simply copy your code and replace the section that reads from the file? I did that and everything is 0.0.

Thanks again!

 

Fiona Z. (Intel) wrote:

Hi arth,

The problem is caused by file read, if you set value to A & B in code, the output should be like below:

You may try following code to save double data in txt with UTF-8, the output should be correct.

std::ifstream fin("matrix3.cpp", ios::binary);
for(int i=0;i<m*n;i++)
     fin>>A;
for(int i=0;i<n*k;i++)
     fin>>B;
fin.close();

Best regards,
Fiona

0 Kudos
ado
Beginner
872 Views

for example, on screen B[0,0]=-0.200728 and so on, if just save these on screen numbers to a file, or typed them in a code, the results would be fine. But -2.00728 is not actually the original full precision number (for example, with 18 decimals it's -0.200728366617113352), so I mean I had to make sure to save/read the binary numbers to reproduce the problem.

Fiona Z. (Intel) wrote:

Hi arth,

The problem is caused by file read, if you set value to A & B in code, the output should be like below:

You may try following code to save double data in txt with UTF-8, the output should be correct.

std::ifstream fin("matrix3.txt");
for(int i=0;i<m*n;i++)
     fin>>A;
for(int i=0;i<n*k;i++)
     fin>>B;
fin.close();

Best regards,
Fiona

0 Kudos
Zhen_Z_Intel
Employee
872 Views

Hi arth,

Sorry, I just pasted with wrong code, I have fixed it. please access attached input file and use updated code. Thank you.

std::ifstream fin("matrix3.txt");
for(int i=0;i<m*n;i++)
     fin>>A;
for(int i=0;i<n*k;i++)
     fin>>B;
fin.close();
0 Kudos
ado
Beginner
872 Views

Hi Fiona,

I think I understand what you meant. That was exactly part of the problem. If you save or type in the on screen printed numbers, the results are all good. Because the on screen numbers are different from the original 8 bytes doubles. It's reduced precision.

My code should be fine to reproduce the problem. What is more interesting is, after you read from the binary file, and change even 1 of the original numbers to a reduced precision number, the result would be good.

For example, after  you read from the binary file, and assign B[0,0]=-0.2.00728 but keep all other numbers as the original full precision ones, then the results would be correct! very weird.

Thanks!

 

Fiona Z. (Intel) wrote:

Hi arth,

Sorry, I just pasted with wrong code, I have fixed it. please access attached input file and use updated code. Thank you.

std::ifstream fin("matrix3.txt");
for(int i=0;i<m*n;i++)
     fin>>A;
for(int i=0;i<n*k;i++)
     fin>>B;
fin.close();

0 Kudos
ado
Beginner
872 Views

Actually I kind of answered my own question. The MKL is calculating correctly, but I myself verified the results using the onscreen printout, which has less precision and due to the large numbers in one of the matrices, the result is different. Thanks for your time! Please close/remove this thread.

0 Kudos
Reply