< 目次

C/C++ コードで複素数値を返す BLAS 関数を呼び出す

関数が返す複素数の制御は C と Fortran で異なります。BLAS は Fortran 形式なので、C から複素数を返す BLAS 関数への呼び出しを制御している場合は注意が必要です。しかし、Fortran では、通常の関数呼び出しに加えて、関数が C プログラムから呼び出されたときに複素数の戻り値を返すように、関数をサブルーチンとして呼び出すことができます。Fortran 関数がサブルーチンとして呼び出された場合、戻り値は呼び出しシーケンスで最初のパラメーターになります。この機能を使用して C から BLAS 関数を呼び出すことができます。

以下の例は、Fortran 関数のサブルーチンとしての呼び出しを C からの呼び出しに変換する方法を示しています (隠しパラメーター result が表示されている点に注意)。

通常の Fortran 関数呼び出し:                   result = cdotc( n, x, 1, y, 1 )

関数をサブルーチンとして呼び出す:  call cdotc( result, n, x, 1, y, 1)

関数をC から呼び出す:                  cdotc( &result, &n, x, &one, y, &one )

インテル® oneAPI マス・カーネル・ライブラリー (インテル® oneMKL) には、Fortran スタイル (大文字と小文字を区別しない) BLAS に大文字、小文字、末尾にアンダースコアが付いた小文字のエントリーポイントがあります。このため、cdotc、cdotc_、および CDOTC はすべて等価です。

上記の例は、C/C++ アプリケーションから複素数を返すレベル 1 BLAS 関数を呼び出す方法の 1 つです。最も簡単な方法は、CBLAS を使用することです。例えば、以下のように CBLAS インターフェイスを使用して、同じ関数を呼び出すことができます。

cblas_cdotc( n, x, 1, y, 1, &result )

この場合、複素数は引数リストの最後になります。

以下に、Fortran 形式の BLAS インターフェイスと CBLAS (C 言語) インターフェイスを C/C++ から使用する方法を示します。

複素レベル 1 BLAS 関数の C からの呼び出し例

次の例は、C プログラムから複素レベル 1 BLAS 関数 zdotc() を呼び出す方法を表しています。この関数は、2 つの倍精度複素ベクトルのドット積を計算します。

この例では、複素数タイプのドット積が構造体 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;
}

この例では、大きなデータサイズの複素ドット積が構造体 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;
 }

複素レベル 1 BLAS 関数の C++ からの呼び出し例

以下は C++ 実装です。

                         
#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;
}
            

BLAS を C から直接呼び出す代わりに CBLAS インターフェイスを使用する例

このサンプルは 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;
}