インテル® MKL 11.3 を使用した行列乗算チュートリアル
インテル® MKL には、行列乗算用のルーチンが用意されています。最も広く利用されるのは、倍精度行列の積を計算する dgemm ルーチンです。
dgemm ルーチンは、いくつかの計算を実行できます。例えば、このルーチンを使用して、A と B の転置または共役転置を実行することができます。dgemm ルーチンの機能の詳細とすべての引数については、『インテル® MKL リファレンス・マニュアル』の ?gemm のトピックを参照してください。
この演習は、変数を宣言し、行列値を配列で格納した後、dgemm を呼び出して行列の積を計算します。これらの行列の格納には配列を使用します。
演習の 1 次元配列は、配列の連続するセルに各列の要素を配置して、行列を格納します。
このチュートリアルの演習の C ソースコードは、<install-dir>\samples_2016\ja\mkl\tutorials.zip (Windows*) または <install-dir>/samples_2016/ja/mkl/tutorials.zip (Linux*/OS X*) を参照してください。
tutorials.zip ファイルを展開すると、Fortran ソースコードは mkl_mmx_f ディレクトリーに配置され、C ソースコードは mkl_mmx_c ディレクトリーに配置されます。
/* C ソースコードは dgemm_example.c を参照 */ #define min(x,y) (((x) < (y)) ? (x) : (y)) #include <stdio.h> #include <stdlib.h> #include "mkl.h" int main() { double *A, *B, *C; int m, n, k, i, j; double alpha, beta; printf ("\n This example computes real matrix C=alpha*A*B+beta*C using \n" " Intel® MKL function dgemm, where A, B, and C are matrices and \n" " alpha and beta are double precision scalars\n\n"); m = 2000, k = 200, n = 1000; printf (" Initializing data for matrix multiplication C=A*B for matrix \n" " A(%ix%i) and matrix B(%ix%i)\n\n", m, k, k, n); alpha = 1.0; beta = 0.0; printf (" Allocating memory for matrices aligned on 64-byte boundary for better \n" " performance \n\n"); A = (double *)mkl_malloc( m*k*sizeof( double ), 64 ); B = (double *)mkl_malloc( k*n*sizeof( double ), 64 ); C = (double *)mkl_malloc( m*n*sizeof( double ), 64 ); if (A == NULL || B == NULL || C == NULL) { printf( "\n ERROR: Can't allocate memory for matrices. Aborting... \n\n"); mkl_free(A); mkl_free(B); mkl_free(C); return 1; } printf (" Intializing matrix data \n\n"); for (i = 0; i < (m*k); i++) { A[i] = (double)(i+1); } for (i = 0; i < (k*n); i++) { B[i] = (double)(-i-1); } for (i = 0; i < (m*n); i++) { C[i] = 0.0; } printf (" Computing matrix product using Intel® MKL dgemm function via CBLAS interface \n\n"); cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, n, k, alpha, A, k, B, n, beta, C, n); printf ("\n Computations completed.\n\n"); printf (" Top left corner of matrix A: \n"); for (i=0; i<min(m,6); i++) { for (j=0; j<min(k,6); j++) { printf ("%12.0f", A[j+i*k]); } printf ("\n"); } printf ("\n Top left corner of matrix B: \n"); for (i=0; i<min(k,6); i++) { for (j=0; j<min(n,6); j++) { printf ("%12.0f", B[j+i*n]); } printf ("\n"); } printf ("\n Top left corner of matrix C: \n"); for (i=0; i<min(m,6); i++) { for (j=0; j<min(n,6); j++) { printf ("%12.5G", C[j+i*n]); } printf ("\n"); } printf ("\n Deallocating memory \n\n"); mkl_free(A); mkl_free(B); mkl_free(C); printf (" Example completed. \n\n"); return 0; }
この演習は、dgemm ルーチンの呼び出し方法を説明します。 実際のアプリケーションでは、行列乗算の結果を使用します。
この dgemm ルーチンの呼び出しは、行列の乗算を行います。
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, n, k, alpha, A, k, B, n, beta, C, n);
引数は、インテル® MKL がどのように演算を行うかを指定するオプションです。ここでは、以下の引数が指定されています。
行列が行優先で格納され、行列の各行の要素が上記の図で示されているように連続して格納されることを示します。
行列 A と B を乗算前に転置または共役転置しないことを示す列挙型。
行列のサイズを示す整数:
A: m 行 k 列
B: k 行 n 列
C: m 行 n 列
行列 A と B の積の測定に使用する実数値。
行列 A の格納に使用する配列。
配列 A のリーディング・ディメンジョン、またはメモリーの連続する列 (列優先で格納する場合) 間の要素の数。この演習では、リーディング・ディメンジョンは列の数と同じです。
行列 B の格納に使用する配列。
配列 B のリーディング・ディメンジョン、またはメモリーの連続する列 (列優先で格納する場合) 間の要素の数。この演習では、リーディング・ディメンジョンは列の数と同じです。
行列 C の測定に使用する実数値。
行列 C の格納に使用する配列。
配列 C のリーディング・ディメンジョン、またはメモリーの連続する列 (列優先で格納する場合) 間の要素の数。この演習では、リーディング・ディメンジョンは列の数と同じです。
インテル® MKL には、さまざまなコンパイラーとサードパーティーのライブラリー、およびインターフェイスと互換性のある、複数のプロセッサーとオペレーティング・システム向けにコードを生成する多くのオプションが用意されています。インテル® Parallel Studio XE Composer Edition でこの演習をコンパイルおよびリンクする場合は、以下のように入力します。
ここでは、https://software.intel.com/en-us/articles/intel-mkl-113-getting-started/ (英語) で説明されているようにインテル® MKL をインストールして環境変数を設定済みであることを想定しています。
ほかのコンパイラーの場合は、インテル® MKL リンクライン・アドバイザー (http://software.intel.com/en-us/articles/intel-mkl-link-line-advisor/ (英語)) を使用して、このチュートリアルの演習をコンパイルおよびリンクするコマンドラインを取得します。
コンパイルとリンクが完了したら、生成された実行ファイル dgemm_example.exe (Windows*) または a.out (Linux*/OS X*) を実行します。
インテル® コンパイラーは、互換マイクロプロセッサー向けには、インテル製マイクロプロセッサー向けと同等レベルの最適化が行われない可能性があります。これには、インテル® ストリーミング SIMD 拡張命令 2 (インテル® SSE2)、インテル® ストリーミング SIMD 拡張命令 3 (インテル® SSE3)、ストリーミング SIMD 拡張命令 3 補足命令 (SSSE3) 命令セットに関連する最適化およびその他の最適化が含まれます。インテルでは、インテル製ではないマイクロプロセッサーに対して、最適化の提供、機能、効果を保証していません。本製品のマイクロプロセッサー固有の最適化は、インテル製マイクロプロセッサーでの使用を目的としています。インテル® マイクロアーキテクチャーに非固有の特定の最適化は、インテル製マイクロプロセッサー向けに予約されています。この注意事項の適用対象である特定の命令セットの詳細は、該当する製品のユーザー・リファレンス・ガイドを参照してください。 改訂 #20110804 |