1072: アプリケーション開発を加速するcudaライブラリ
TRANSCRIPT
アプリケーションをGPUで加速する方法
Application
Library
GPU対応ライブラリにチェンジ簡単に開始
CUDAOpenACC
主要処理をCUDAで記述高い自由度
既存コードにディレクティブを挿入簡単に加速
ソフトウェア階層
GPU(Tesla, Quadro, GeForce, Tegra)
CUDA Runtime/Driver
Application
Third-party
Libraries
NVIDIA
LibrariesOpenACC
Runtime
GPU対応のライブラリ (一部)
NVIDIA cuBLAS NVIDIA cuRAND
NVIDIA cuSPARSEVector Signal
Image ProcessingGPU AcceleratedLinear Algebra
NVIDIA cuFFT
C++ STL Features for CUDA
Sparse Linear AlgebraIMSL Library
Matrix Algebra on GPU and Multicore
NVIDIA cuDNN
NVIDIA AmgX
NVIDIAライブラリ
cuFFT フーリエ変換cuBLAS 行列演算(密行列)
cuSPARSE 行列演算(疎行列)
cuSOLVER 行列ソルバ (y=Ax)
cuDNN ディープラーニングcuRAND 乱数生成Thrust C++テンプレート(STLベース)
NPP 画像処理プリミティブ
ライブラリのインタフェース
デバイスAPIGPUカーネルから呼び出すAPI
ホストAPIホスト(CPU)から呼び出すAPI (今回は主にこちらを説明)
XTインターフェースマルチGPU: 自動対応、複数GPUへの明示的な処理振り分けは不要
明示的なデータ転送は不要: 必要なデバイスメモリはライブラリが確保
Out-of-core: GPUメモリに収まらない問題に対応
オーバーラップ: カーネル実行とデータ転送を同時実行
NVIDIAライブラリ(ホストAPI)の典型的な使い方
1. ハンドルの作成
2. デバイスメモリの確保
3. 入力データの転送 (ホスト デバイス)
4. 入力データ形式の変換
5. 実行
6. 出力データ形式の変換
7. 出力データの転送 (デバイス ホスト)
8. デバイスメモリの解放
9. ハンドルの削除
ハンドルの作成
ハンドル: ライブラリの各種設定・情報を格納するオブジェクトライブラリ操作・実行は全てハンドル経由で実施 (第1引数がハンドル)
cublasHandle_t handle;
cublasCreate( & handle );
cuBLAS
cusparseHandle_t handle;
cusparseCreate( & handle );
cuSPARSE
cufftHandle plan;
cufftHandle1d( & plan, … );
cuFFT
curandGenerator_t gen;
curandCreateGenerator( & gen, … );
cuRAND
cudnnHandle handle;
cudnnCreate( & handle, … );
cuDNN
デバイスメモリの確保
cudaMalloc()ライブラリ計算の入出力に使われる領域は、通常のCUDA APIで確保
ライブラリ内部のワーキングメモリは自動で確保される
cudaMallocManaged()Unified Memoryも使用可能 (プロトタイプ開発に最適)
明示的なデータ転送は不要
XTインタフェース: 専用メモリ確保ルーチン(例) cuFFT: cufftXtMalloc()
データ転送
cudaMemcpy()入力データ、出力データの転送は、通常CUDA APIで実施
ライブラリに専用データ転送ルーチンがある場合は、それを使用cuBLAS(ベクトル): cublasSetVector(), cublasGetVector()
cuBLAS(行列): cublasSetMatrix(), cublasGetMatrix()
データ形式の変換
ホストライブラリとGPUライブラリで、対応データ形式が異なる場合に必要
行列(2次元配列): 行優先 列優先
疎行列: 独自? CSR, BSR
cuSPARSE: 疎行列データ形式の変換ルーチン
FFT(周波数空間): 独自? cuFFT形式
データ形式変換は用途に応じてホスト上 or GPU上で
実行
計算をGPUにオフロード
cuBLAS: cublasSgemm( handle, … )
cuSPARSE: cusparseScsrmv( handle, … )
cuSOLVER: cusolverDnSgetrf( handle, … )
cuFFT: cufftExecR2C( plan, … )
cuDNN: cudnnConvolutaionForward( handle, … )
cuRAND: curandGenerateUniform( gen, … )
cuBLAS適用例
for ( int j = 0; j < N; j++ ) {
for ( int i = 0; i < M; i++ ) {
for ( int k = 0; k < K; k++ ) {
C[ j*ldc + i ] = A[ k*lda + i ] * B[ j*ldb + k ];
}
}
}
行列乗算
C = A x B
CA
B
M
N
K
K
cuBLAS適用例
行列乗算(BLAS)C = A x B
CA
B
M
N
K
K
sgemm( ‘n’, ‘n’, M, N, K, 1.0, A, lda, B, ldb, 0.0, C, ldc );
cuBLAS適用例
cublasCreate( &handle );
cudaMalloc( &d_A, sizeof(float) * M * K );
cudaMalloc( &d_B, sizeof(float) * K * N );
cudaMalloc( &d_C, sizeof(float) * M * N );
cublasSetMatrix( M, K, sizeof(float), A, lda, d_A, lda );
cublasSetMatrix( K, N, sizeof(float), B, ldb, d_B, ldb );
cublasSgemm( handle, ‘n’, M, N, K, 1.0, A, lda, B, ldb, 0.0, C, ldc );
cublasSetMatrix( M, N, sizeof(float), d_C, ldc, C, ldc );
ハンドルの作成
デバイスメモリの確保
入力データの転送
出力データの転送
実行
cuBLAS適用例
前処理 + 行列乗算 + 後処理
for ( k = 0; k < K; k++ )
for ( i = 0; i < M; i++ )
A[ k*lda + i ] = … ;
sgemm( ‘n’, ‘n’, M, N, K, 1.0, A, lda, B, ldb, 0.0, C, ldc );
for ( j = 0; j < N; j++ )
for ( i = 0; i < M; i++ )
C[ j*ldc + i ] = … ;
CUDAとの併用
…
cublasSetMatrix( M, K, sizeof(float), A, lda, d_A, lda );
cublasSetMatrix( K, N, sizeof(float), B, ldb, d_B, ldb );
kernel_update_A<<< … >>>( d_A, lda, … );
cublasSgemm( handle, ‘n’, M, N, K, 1.0, A, lda, B, ldb, 0.0, C, ldc );
kernel_update_C<<< … >>>( d_C, ldc, … );
cublasSetMatrix( M, N, sizeof(float), d_C, ldc, C, ldc );
ライブラリ
CUDAカーネル
CUDAカーネル
OpenACCとの併用
#pragma acc data copyin(A, B) copyout(C)
{
#pragma acc parallel
for ( k = 0; k < K; k++ )
for ( i = 0; i < M; i++ )
A[ k*lda + i ] = … ;
#pragma acc host_data use_device(A, B, C)
{ cublasSgemm( handle, ‘n’, M, N, K, 1.0, A, lda, B, ldb, 0.0, C, ldc ); }
#pragma acc parallel
for ( j = 0; j < N; j++ )
for ( i = 0; i < M; i++ )
C[ j*ldc + i ] = … ;
}
ライブラリ
OpenACC
OpenACC
非同期実行、オーバーラップ
CUDAストリーム
cublasCreate( & handle );
cudaStreamCreate( & stream_0, … );
cudaStreamCreate( & stream_1, … );
cublasSetStream( handle, stream_0 );
cublasSgemm( handle, … );
cublasSetStream( handle, stream_1 );
cublasSgemm( handle, … );
ストリーム0
ストリーム1
1スレッド/2GPU: OK
2スレッド/2GPU: OK
マルチスレッド、マルチGPU
cudaSetDevice( 0 );
cusparseCreate( & handle );
cusparseScsrmv…( handle, … );
cudaSetDevice( 1 );
cusparseCreate( & handle );
cusparseScsrmv…( handle, … )
スレッド0 スレッド1
cudaSetDevice( 0 );
cusparseCreate( & handle_0 );
cudaSetDevice( 1 );
cusparseCreate( & handle_1 );
cusparseScsrmv…( handle_0, … );
cusparseScsrmv…( handle_1, … );
2スレッド/1GPU: OKライブラリハンドルを複数スレッドで共有可能 (スレッドセーフ)
cuFFT: FFTライブラリ複素数と実数(C2C, R2C, C2R)
単精度(32-bit)、倍精度(64-bit)
1D,2D,3D変換
バッチ変換 (複数のfftを同時実行)
データ形式はfftw互換
fftwからの移行ツール
NVIDIA cuFFT
cuFFT: FFTライブラリXTインタフェース対応: cufftXT API
最大4GPUs
Callbackルーチン
前処理と後処理をCallbackとして設定
NVIDIA cuFFT
Read input
Convert to 32-bit
Write 32-bit
ReadPerform
FFTWrite
Read FFT
output
Convert to 8-bit
Write 8-bit data
Read input
Convert to 32-bit
Perform FFT
Convert to 8-bit
Write 8-bit data
Callback無: 3カーネル
Callback有: 1カーネル
cuFFT: 最大700 GFLOPS
0
100
200
300
400
500
600
700
800
1 1,000 1,000,000
GFLO
PS
Transform Size
単精度(32bit)
Powers of 2
Powers of 3
Powers of 5
Powers of 7
0
50
100
150
200
250
300
350
1 1,000 1,000,000
GFLO
PS
Transform Size
倍精度(64bit)
Performance may vary based on OS and software
versions, and motherboard configuration
• cuFFT 7.0 on K40m, Base clocks, ECC ON
• Batched transforms on 28M-33M total elements, input and output data on device
• Excludes time to create cuFFT “plans”
1D複素数バッチ FFTs
(信号処理, 2D/3D FFTのコンポーネント)
cuFFT: 性能改善 (CUDA 6.5 7.0)
1x
2x
3x
4x
5x
0 20 40 60 80 100 120 140
Speedup
Transform Size
1D 単精度 Complex-to-Complex バッチFFTs
Size = 23 Size = 66Size = 31Size = 110
Size = 121
Performance may vary based on OS and software
versions, and motherboard configuration
• cuFFT 6.5 and 7.0 on K20m, ECC ON
• Batched transforms on 32M total elements, input and output data on device
• Excludes time to create cuFFT “plans”
cuBLAS: 密行列演算ライブラリ
全てのBLAS関数 + BLASライク関数
全152 BLAS関数をサポート
単精度と倍精度、実数と複素数: S,D,C,Z
ホストAPIとデバイスAPI
バッチ関数 (多数の小さな問題)
gemmBatched(), trsmBatched(), matinvBatched()
XTインタフェース: cublasXt API (Level-3 BLAS)
マルチGPUs
Out-of-core (デバイスメモリ容量を超えるサイズの行列)
“Drop-in” (CPU BLASをそのまま置き換え)
NVIDIA cuBLAS
cuBLAS: 密行列演算ライブラリ
ディープラーニング向け機能強化
cublasSgemmEx()
演算は32-bit(FP32)、入出力は8-bit(int8)/16bit(FP16)
より大きな行列をGPUメモリに常駐可能
cublasHgemm()
FP16用の行列積 (演算と入出力、全てFP16)
Pascalから利用可能 (現在はTegra X1のみ利用可能)
NVIDIA cuBLAS
cuBLAS: 単精度:>3 TF, 倍精度:>1 TF
0
500
1,000
1,500
2,000
2,500
3,000
3,500SG
EM
M
SSY
MM
ST
RSM
SSY
RK
CG
EM
M
CSY
MM
CT
RSM
CSY
RK
DG
EM
M
DSY
MM
DT
RSM
DSY
RK
ZG
EM
M
ZSY
MM
ZT
RSM
ZSY
RK
Single Single Complex Double Double Complex
GFLO
PS
• cuBLAS 7.0 on K40m, Base clocks, ECC ON, input and output data on device
• m=n=k=4096, transpose=no, side=right, fill=lowerPerformance may vary based on OS and software
versions, and motherboard configuration
cuBLAS-XT: >12 TF (3 GPUs on 1ノード)
0
2,000
4,000
6,000
8,000
10,000
12,000
14,000
SG
EM
M
SSY
RK
ST
RSM
CG
EM
M
CSY
RK
DG
EM
M
DSY
RK
DT
RSM
ZG
EM
M
ZSY
RK
ZT
RSM
Single SingleComplex
Double DoubleComplex
GFLO
PS 1xK80
3xK80
• cuBLAS 7.0 on K80, Base clocks, ECC ON
• input and output data on host, m=n=k=32768, transpose=noPerformance may vary based on OS and software
versions, and motherboard configuration
cuSPARSE: 疎行列演算ライブラリ
疎行列用BLAS
Level-2: 疎行列 x ベクトル
Level-3: 疎行列 x 密行列
様々な行列格納フォーマット
COO, CSR, CSC, ELL, HYB, BSR, BSRX, Dense
フォーマット変換関数: (例) coo2csr(), csr2dense()
1.0
2.0
3.0
4.0
y1
y2
y3
y4
𝛼 + 𝛽
1.0
6.0
4.0
7.0
3.02.0
5.0
y1
y2
y3
y4
NVIDIA cuSPARSE
cuSPARSE: 疎行列演算ライブラリ
自然言語処理向け機能拡張
密行列 x 疎ベクトル
cusparse<T>gemvi()
y = α ∗ op(A) ∗ x + β ∗ y
-
2
-
-
1
y1
y2
y3
α + βy1
y2
y3
A11
A21
A31
A12
A22
A32
A13
A23
A33
A14
A24
A34
A15
A25
A35
密行列密ベクトル 疎ベクトル
(例) テキスト内の単語の出現頻度
NVIDIA cuSPARSE
cuSPARSE: 性能比較
0x
1x
2x
3x
4x
5x
Speedup o
ver
MK
L
疎行列 x 密ベクトル (SpMV)
• Average of S/C/D/Z routines
• cuSPARSE 7.0 on K40m, Base clocks, ECC ON, input and output data on device
• MKL 11.0.4 on Intel Xeon Haswell single-socket 16-core E5-2698 v3 @ 2.3GHz, 3.6GHz Turbo
• Matrices obtained from: http://www.cise.ufl.edu/research/sparse/matrices/
Performance may vary based on OS and software
versions, and motherboard configuration
前処理付きCG法とグラフ・カラーリング
Input
matrix
Analysis and
ILU(0)(cuSPARSE)
Solve(cuSPARSE)
Input
matrix
Reorder
matrix(Thrust)
Analysis and
ILU(0)(cuSPARSE)
Solve(cuSPARSE)
Graph
coloring (cuSPARSE)
カラーリングとリオーダーリングにより並列性を抽出
並列性向上により性能UP
入力行列の特性が悪いと(並列性抽出が難しいと)性能が上がらない
cuSPARSE: 不完全LU分解の高速化
20x 28x 9x
0x
1x
2x
3x
4x
5x
6x
Speedup
• cuSPARSE 7.0 on K40c
• Matrices obtained from: http://www.cise.ufl.edu/research/sparse/matrices/Performance may vary based on OS and software
versions, and motherboard configuration
グラフカラーリングによる不完全LU分解(ILU0)の高速化
Full results at: research.nvidia.com/publication/parallel-graph-coloring-applications-incomplete-lu-factorization-gpu
cuSOLVER: 行列ソルバー
密な線形方程式系、疎な線形方程式系、固有値問題を解くためのサブルーチン
3つのAPI:
Dense: cuSolverDN
Sparse: cuSolverSP
Refactorization: cuSolverRN
cuSOLVER: Dense
LAPACK(密行列直接ソルバーライブラリ)のサブセット
コレスキー分解: potrf(), potrs()
LU分解: getrf(), getrs()
QR分解: geqrf(), ormqr()
Bunch-Kaufman分解: sytrf()
特異値分解: gebrd(), gesvd()
適用分野
コンピュータ・ビジョン、最適化、CFD
cuSOLVER: Sparse
スパース直接法ソルバー
Solve 𝐴𝑥 = 𝑏: csrlsvlu(), csrlsvqr(), csrlsvchol()
Solve min |𝐴𝑥 − 𝑏|: csrsqvqr()
Solve 𝐴𝑥 = 𝜆𝑥: csreigvsi()
適用分野
Well models in Oil & Gas
非線形ニュートン法
cuSOLVER: Dense性能 (vs. MKL)
0
200
400
600
800
1,000
1,200
1,400
1,600
1,800SPO
TR
F
DPO
TR
F
CPO
TR
F
ZPO
TR
F
SG
ET
RF
DG
ET
RF
CG
ET
RF
ZG
ET
RF
SG
EQ
RF
DG
EQ
RF
CG
EQ
RF
ZG
EQ
RF
CholeskyFactorization
LUFactorization
QRFactorization
GFLO
PS
cuSOLVER
MKL
Performance may vary based on OS and software
versions, and motherboard configuration
• cuSOLVER 7.0 on K40c, ECC ON, M=N=4096
• MKL 11.0.4 on Intel Xeon Haswell 14-core E5-2697 v3 @ 3.6GHz
cuSOLVER: Sparse性能
2.0x
11.3x
1.9x1.4x 1.2x
0x
2x
4x
6x
8x
10x
12x
1138_bus Chem97ZtZ Muu ex9 nasa1824
Spe
ed
up
ove
r C
PU
Analysis, Factorization and Solve
• cuSOLVER 7.0 on K40c, ECC ON
• SuiteSparse v4.4 on Intel Xeon Haswell 14-core E5-2697 v3 @ 3.6GHz
• Matrices obtained from: http://www.cise.ufl.edu/research/sparse/matrices/
Performance may vary based on OS and software
versions, and motherboard configuration
cuDNNディープラーニング用ライブラリ
DLのトレーニングに最適
畳み込み計算を高速化 (2D,3D)
プーリング、ソフトマックス、活性化にも対応
主要DLプラットフォームが採用Caffe, Torch, Theano
NVIDIA cuDNN
cuBLAS
LeNet5 [LeCun et al.,1998]
コンボリューション層 フルコネクション層
cuDNN: APIs
ConvolutionscudnnConvolutionForward()
cudnnConvolutionBackward[Bias|Filter|Data]()
ActivationcudnnActivationForward()
cudnnActivationBackward()
PoolingcudnnPoolingForward()
cudnnPoolingBackward()
SoftmaxcudnnSoftmaxForward()
cudnnSoftmaxBackward()
…
NVIDIA cuDNN
cuDNN: 性能
1.0x 1.0x
1.6x
1.2x
Caffe(GoogLeNet)
Torch(OverFeat)
Baseline (GPU) With cuDNN
2.5M
18M
23M
43M
0
10
20
30
40
50
16 Core CPU GTX Titan Titan BlackcuDNN v1
Titan XcuDNN v2
Millions
of
Images
Images Trained Per Day (Caffe AlexNet)
E5-2698 v3 @ 2.3GHz
AlexNet [A. Krizhevsky et al.,2012]
cuDNN: v3
より大きなモデルFP16ストレージ
学習の高速化Maxwell向け最適化
2D畳み込み演算の高速化
FFTコンボリューション対応
アルゴリズム選択: GEMM, DIRECT, FFT
https://developer.nvidia.com/cuDNN
0.0x
0.5x
1.0x
1.5x
2.0x
2.5x
Alexnet OverFeat VGG
cuDNN v2 cuDNN v3
学習性能: 最大2倍
cuDNN 3 performance vs. previous version on Ubuntu 14.04 LTS with
NVIDIA® GeForce® TITAN X and Intel® Core™ i7-4930K @ 3.40GHz
cuRAND: 乱数生成ライブラリ
ホストAPI: 多数の乱数をデバイスメモリ上に生成
デバイスAPI: スレッド毎に乱数を生成
分布タイプ: uniform, normal, log-normal, poisson
乱数タイプ:
NVIDIA cuRAND
擬似乱数(Pseudo-random)
XORWOW
MRG32K3A
MTGP32
PHILOX4_32_10
MT19937
準乱数(Quasi-random)
SOBOL32
SCRAMBLED_SOBOL32
SOBOL64
SCRAMBLED_SOBOL64
Mersenne Twister 19937
cuRAND: 高性能
0
2
4
6
8
10
12
14
16
18
XORWOW Philox MRG32k3a MTGP32 Sobol32Scrambled
Sobol64Scrambled
Pseudo-random Quasi-random
Gsa
mple
s /
sec
Uniform Distribution Normal Distribution Log-Normal Distribution
• cuRAND 7.0 on K40m, Base clocks, ECC ON, double-precision input and output data on devicePerformance may vary based on OS and software
versions, and motherboard configuration
cuRAND: 50倍以上高速 (vs. MKL)
0
2
4
6
8
10
12
14
16
Sobol32 MRG32k3a Sobol32 MRG32k3a Sobol32 MRG32k3a
Uniform Distribution Normal Distribution Log-Normal Distribution
GSam
ple
s /
sec
cuRAND
MKL
• cuRAND 7.0 on K40m, Base clocks, ECC ON, double-precision input and output data on device
• MKL 11.0.1 on Intel Xeon Haswell single-socket 16-core E5-2698 v3 @ 2.3GHz, 3.6GHz TurboPerformance may vary based on OS and software
versions, and motherboard configuration
Thrust: CUDA C++ 並列テンプレートライブラリ
C++ STLライクなテンプレートライブラリ
迅速なアプリ開発、プロトタイプ開発
GPU最適化な並列アルゴリズム
sort, reduce, scan, 他
ポータブル: CPUでも利用可能
OpenMP, TBB
GitHub: thrust.github.com
C++ STL Features for CUDA
Thrust: 性能改善 (CUDA 6.5 7)
sort: 1.1–1.8倍
(ユーザ定義型は3倍)
merge: 2倍
scan: 1.15倍
reduce_by_key: 1.25倍
thrust::count_if(thrust::cuda::par.on(stream1), text, text+n, myFunc());
New in
CUDA 7.0
1.7x 1.8x
1.2x1.1x
1.3x1.1x
0.0x
0.5x
1.0x
1.5x
2.0x
char short int long float double
Speedup
Sort (32M samples)
• CUDA 7.0 and 6.5 on K40m, ECC ON, input and output data on device
• Performance may vary based on OS and software versions, and motherboard
configurationCUDAストリーム対応