Visible to Intel only — GUID: GUID-A0908E50-19D7-44C1-A068-44036B466BC7
Visible to Intel only — GUID: GUID-A0908E50-19D7-44C1-A068-44036B466BC7
Calling BLAS Functions that Return the Complex Values in C/C++ Code
Complex values that functions return are handled differently in C and Fortran. Because BLAS is Fortran-style, you need to be careful when handling a call from C to a BLAS function that returns complex values. However, in addition to normal function calls, Fortran enables calling functions as though they were subroutines, which provides a mechanism for returning the complex value correctly when the function is called from a C program. When a Fortran function is called as a subroutine, the return value is the first parameter in the calling sequence. You can use this feature to call a BLAS function from C.
The following example shows how a call to a Fortran function as a subroutine converts to a call from C and the hidden parameter result gets exposed:
Normal Fortran function call: result = cdotc( n, x, 1, y, 1 )
A call to the function as a subroutine: call cdotc( result, n, x, 1, y, 1)
A call to the function from C: cdotc( &result, &n, x, &one, y, &one )
Intel® oneAPI Math Kernel Library has both upper-case and lower-case entry points in the Fortran-style (case-insensitive) BLAS, with or without the trailing underscore. So, all these names are equivalent and acceptable:cdotc, CDOTC, cdotc_, and CDOTC_.
The above example shows one of the ways to call several level 1 BLAS functions that return complex values from your C and C++ applications. An easier way is to use the CBLAS interface. For instance, you can call the same function using the CBLAS interface as follows:
cblas_cdotc( n, x, 1, y, 1, &result )
The complex value comes last on the argument list in this case.
The following examples show use of the Fortran-style BLAS interface from C and C++, as well as the CBLAS (C language) interface:
- Example "Calling a Complex BLAS Level 1 Function from C"
- Example "Calling a Complex BLAS Level 1 Function from C++"
- Example "Using CBLAS Interface Instead of Calling BLAS Directly from C"
Example "Calling a Complex BLAS Level 1 Function from C"
The example below illustrates a call from a C program to the complex BLAS Level 1 function zdotc(). This function computes the dot product of two double-precision complex vectors.
In this example, the complex dot product is returned in the structure c.
#include "mkl.h"
#define N 5
int main()
{
int n = N, inca = 1, incb = 1, i;
MKL_Complex16 a[N], b[N], c;
for( i = 0; i < n; i++ )
{
a[i].real = (double)i; a[i].imag = (double)i * 2.0;
b[i].real = (double)(n - i); b[i].imag = (double)i * 2.0;
}
zdotc( &c, &n, a, &inca, b, &incb );
printf( "The complex dot product is: ( %6.2f, %6.2f)\n", c.real, c.imag );
return 0;
}
In this example, the complex dot product for large data size is returned in the structure c.
#include "mkl.h"
#define N 5
int main()
{
MKL_INT64 n = N, inca = 1, incb = 1, i;
MKL_Complex16 a[N], b[N], c;
for( i = 0; i < n; i++ )
{
a[i].real = (double)i; a[i].imag = (double)i * 2.0;
b[i].real = (double)(n - i); b[i].imag = (double)i * 2.0;
}
zdotc_64( &c, &n, a, &inca, b, &incb );
printf( "The complex dot product is: ( %6.2f, %6.2f)\n", c.real, c.imag );
return 0;
}
Example "Calling a Complex BLAS Level 1 Function from C++"
Below is the C++ implementation:
#include <complex>
#include <iostream>
#define MKL_Complex16 std::complex<double>
#include "mkl.h"
#define N 5
int main()
{
int n, inca = 1, incb = 1, i;
std::complex<double> a[N], b[N], c;
n = N;
for( i = 0; i < n; i++ )
{
a[i] = std::complex<double>(i,i*2.0);
b[i] = std::complex<double>(n-i,i*2.0);
}
zdotc(&c, &n, a, &inca, b, &incb );
std::cout << "The complex dot product is: " << c << std::endl;
return 0;
}
Example "Using CBLAS Interface Instead of Calling BLAS Directly from C"
This example uses CBLAS:
#include <stdio.h>
#include "mkl.h"
typedef struct{ double re; double im; } complex16;
#define N 5
int main()
{
int n, inca = 1, incb = 1, i;
complex16 a[N], b[N], c;
n = N;
for( i = 0; i < n; i++ )
{
a[i].re = (double)i; a[i].im = (double)i * 2.0;
b[i].re = (double)(n - i); b[i].im = (double)i * 2.0;
}
cblas_zdotc_sub(n, a, inca, b, incb, &c );
printf( "The complex dot product is: ( %6.2f, %6.2f)\n", c.re, c.im );
return 0;
}