Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Gianluca_G_
Beginner
96 Views

C# Multiplication

hello,
I am trying the MKL Library, in particular I am finding some problems with the multiplication.

This is a simple example in C# where a multiply two squared Complex matrix, the result is very strange because the first row have very high values and the second row zero values.

Some one can help me to understand the issue?

 

        public static int LAPACK_ROW_MAJOR = 101;
        public static int LAPACK_COL_MAJOR = 102;

        //TRANSPOSE
        public static int CBLAS_NO_TRANS = 111; 
        public static int CBLAS_TRANS = 112;
        public static int CBLAS_CONJ_TRANS = 113;

        /** CBLAS native cblas_cgemm declaration */
        [DllImport("mkl_rt.dll", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
        internal static extern void cblas_cgemm(
            int matrix_layout, 
            int TransA, 
            int TransB, 
            int M, 
            int N, 
            int K,
            Complex alpha, 
            [In] Complex[] A, 
            int lda, 
            [In] Complex[] B, 
            int ldb,
            Complex beta, 
            [In, Out] Complex[] C, 
            int ldc
        );


        public static void MulTest()
        {
            Complex[] a = { 1, 2, 3, 4 };
            Complex[] b = { 5, 6, 7, 8 };

            int m = 2;
            int n = 2;
            int k = 2;

            Complex[] c = new Complex[m * n];

            Complex alpha = 1;
            Complex beta = 0;

            int lda = k;
            int ldb = n;
            int ldc = n;

            MKLWrapper.cblas_cgemm(LAPACK_ROW_MAJOR, CBLAS_NO_TRANS, CBLAS_NO_TRANS, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);

        }

 

Thank You very much

Gianluca

0 Kudos
7 Replies
Anthony_H_Intel1
Employee
96 Views

I'm unfamiliar with the C# implementation of the Complex data type being used here, but it looks like the intent is to create 2x2 Complex matrices A and B, yet only 4 values are used to initialize each. It should require a real and imaginary component for each element of each matrix. In this case are the imaginary parts of each entry of A and B initialized to 0? If this is the case then sgemm should suffice.

After calling cgemm I'm not sure how you're reading off the elements of C, or what is meant by "very high values" but the "very high values" might correspond to the real components of each entry in C (ie, calling sgemm on real matrices A,B)  and the "zeros" might correspond to the imaginary components of each entry of C, which would indeed be zero everywhere if A and B were initialized with imaginary part equal to 0.

Could you please include your entire source? It would helpful if I could see specifically how C is being read after cgemm is called, and implementation of the Complex type.  

Anthony

 

 

Gianluca_G_
Beginner
96 Views

 

The matrices are both 2x2 . I also tried with more complex matrix, with real and imaginary values different than zero, but I had the same strange results. Then I have created a simple example to submit to you.

As you understand the inizialization code set only the real part while the imaginary is set to zero.

The results values in this case correspond only to the real part. The result, with x64 dlls in this example is:

-148096, 0
-219636, 0
0, 0
0, 0

While with x86 every value is zero.

 

I am working with MKL 11.3.1 version and the dlls that  I found this in "C:\Program  Files  (x86)\IntelSWTools\compilers_and_libraries_2016.0.110\windows\redist\" folder, after that "Intel Paralled Studio" was installed. 

The example I commited is the complete version, as you can see is extremely simple. The result is in c vector.

Gianluca

 

Gianluca

Anthony_H_Intel1
Employee
96 Views

Thank you, in this case the System.Numerics implementation of Complex takes the form Complex(Double, Double), whereas cgemm takes as input single precision complex types. I was able to reproduce your results and found that replacing the call from cgemm to a call to zgemm gives the expected results.  Hope this helps.

 

 

Gianluca_G_
Beginner
96 Views

Thank you very much 

Gianluca_G_
Beginner
96 Views

 

I'm sorry to say that it works partially, because with x64 platform is ok, but with x86 returns all zero values. Any idea?

 

Ying_H_Intel
Employee
96 Views

Hi Gianluca G, 

I happened to review several C# issue, so saw your questions here. 

As the cblas_zgemm and cblas_cgemm ask address of alpha and beta, not value. 

void cblas_zgemm (const CBLAS_LAYOUT Layout, const CBLAS_TRANSPOSE transa, const
CBLAS_TRANSPOSE transb, const MKL_INT m, const MKL_INT n, const MKL_INT k, const void  *alpha, const void *a, const MKL_INT lda, const void *b, const MKL_INT ldb, const void *beta, void *c, const MKL_INT ldc);

So you may change 

 [DllImport("mkl_rt.dll", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
        internal static extern void cblas_zgemm(
             int matrix_layout,
             int TransA,
             int TransB,
             int M,
             int N,
            int K,
            ref Complex alpha,
            [In] Complex[] A,
             int lda,
            [In] Complex[] B,
            int ldb,
            ref Complex beta,
            [In, Out] Complex[] C,
             int ldc
        );

MKLWrapper.cblas_zgemm( LAPACK_ROW_MAJOR,  CBLAS_NO_TRANS,  CBLAS_NO_TRANS,  m,  n,  k, ref alpha, a,  lda, b,  ldb, ref beta, c,  ldc)

and try it out. 

Regards,

Ying

Ying_H_Intel
Employee
96 Views

Hi Gianluca, 

It should be able to solve the problem of  x86 returns all zero values. 

Best Regards,

Ying

Reply