インテル® マス・カーネル・ライブラリー 11.2 ユーザーズガイド
関数が返す複素数の制御は 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 )
インテル® マス・カーネル・ライブラリー (インテル® MKL) では、Fortran 形式の (大文字と小文字を区別しない) BLAS で大文字と小文字の両方のエントリーポイントを使用できます (末尾の下線の有無を含む)。このため、cdotc、CDOTC、cdotc_、CDOTC_ はすべて等価です。
上記の例は、C/C++ アプリケーションから複素数を返すレベル 1 BLAS 関数を呼び出す方法の 1 つです。最も簡単な方法は、CBLAS を使用することです。例えば、以下のように CBLAS インターフェースを使用して、同じ関数を呼び出すことができます。
cblas_cdotc( n, x, 1, y, 1, &result )
この場合、複素数は引数リストの最後になります。
以下に、Fortran 形式の BLAS インターフェイスと CBLAS (C 言語) インターフェイスを C/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 <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; }
このサンプルは 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; }