超音波流体屋のプログラム備忘録
CULA Dense (R17, CUDA 5.5)
最終更新:
usapfrog
-
view
(CUDA 5.5, CULA Dense R17 版の情報です。)
アカデミックならFull Editionが使える。
ダウンロードは以下からID登録してから。
http://www.culatools.com/downloads/dense/
linuxは落としてきた.runを管理者権限でbashで実行。
ダウンロードは以下からID登録してから。
http://www.culatools.com/downloads/dense/
linuxは落としてきた.runを管理者権限でbashで実行。
ソース
CULA使い方の一例として、連立方程式 Ax = bを解く話。
んで今回はMatlab記法で A=ones(10 000, 10 000)-eye(10 000); b=ones(10 000, 1);
対角成分だけ0、後は1の行列。解は確か全部 1/9999。
んで今回はMatlab記法で A=ones(10 000, 10 000)-eye(10 000); b=ones(10 000, 1);
対角成分だけ0、後は1の行列。解は確か全部 1/9999。
- #include <stdio.h>
- #include <stdlib.h>
-
- #include <cuda_runtime.h>
- #include <helper_functions.h>
- #include <helper_cuda.h>
- #include <cula.h>
-
-
- int main(int argc, char** argv){
-
- int devID = findCudaDevice(argc, (const char **)argv);
- culaStatus s; //失敗するとculaNoError以外が入るらしい
- s = culaInitialize();
-
- //ホスト領域の確保・値の代入
- double *a, *b;
- int n=10000;
- int m=10000;
- //やってみたらいわゆるColumn-major, CLapackと同じらしい
- int i, j;
- for(i=0; i<n; i++){
- for(j=0; j<m; j++){
- a[i+j*n]= (double) (i != j);
- }
- b[i] = 1;
- }
- //その他、行数・列数情報。CLapackと同じ。
- int ipiv[n];
- int nrhs = 1;
- int lda = n;
- int ldb = n;
-
- //実行・タイマー測定
- StopWatchInterface *timer = 0;
- sdkCreateTimer(&timer);
- sdkStartTimer(&timer);
-
- //連立方程式を解く。これ1行。
- s = culaDgesv(n, nrhs, a, lda, ipiv, b, ldb);
-
- //タイマーストップ
- sdkStopTimer(&timer);
- sdkDeleteTimer(&timer);
-
- //エラー処理等したければ。 正常終了なら0が返る。
-
- //結果表示
- for(j=0; j<m; j++) {
- }
-
- //終了処理
- culaShutdown();
- return 0;
- }
-
環境変数
.bashrcあたりに以下の記述を突っ込んどく
- export CUDA_ROOT=/usr/local/cuda-5.5
- export CULA_ROOT=/usr/local/cula
- export CULA_INC_PATH=$CULA_ROOT/include
- export CULA_LIB_PATH_64=$CULA_ROOT/lib64
- export CUDA_INCPATH=$CUDA_ROOT/include:$CUDA_ROOT/samples/common/inc:$CULA_INC_PATH
-
- export PATH=$CUDA_ROOT/bin:$PATH
- export LD_LIBRARY_PATH=$CUDA_ROOT/lib64:$CULA_LIB_PATH_64:$LD_LIBRARY_PATH
- export LIBRARY_PATH=$LD_LIBRARY_PATH
- export C_INCLUDE_PATH=$CUDA_INCPATH:$C_INCLUDE_PATH
- export CPLUS_INCLUDE_PATH=$CUDA_INCPATH:$CPLUS_INCLUDE_PATH
-
コンパイル
Nsightが便利なので、そっちを使いましょう。
CULAのライブラリの登録だけ必要。プロジェクト右クリックで、
Properties → Build → Settings
Tool Settingsタブ → NVCC Linker → Libraries
Addのアイコン → でてきたダイアログに cula_lapack
CULAのライブラリの登録だけ必要。プロジェクト右クリックで、
Properties → Build → Settings
Tool Settingsタブ → NVCC Linker → Libraries
Addのアイコン → でてきたダイアログに cula_lapack
Makefileならこんな感じ。
- CC=nvcc
- ARCH=-arch=sm_13
- LIB=-lcula_lapack
- SRC=sample.cu
- OUT=sample.out
- all:
- ${CC} ${ARCH} ${SRC} -o ${OUT} ${LIB}
-
計算時間
Nvidia Tesla K20 で 1.8秒。
倍精度なので値も正確。
倍精度なので値も正確。
あらかじめGPUに格納しときたいときは
culaDeviceSgesvほかdevice系の関数を使う。
行列Aとベクトルbに対応する領域、加えて関数に必要な配列ipivなども忘れずにデバイス上に確保してから、
同様の関数を採用すればよい。上記42行付近は以下の通りに書き換える。
行列Aとベクトルbに対応する領域、加えて関数に必要な配列ipivなども忘れずにデバイス上に確保してから、
同様の関数を採用すればよい。上記42行付近は以下の通りに書き換える。
- {
- double *da, *db;
- int *dipiv;
- cudaMalloc((void**) &da, sizeof(double)*n*n);
- cudaMalloc((void**) &db, sizeof(double)*n);
- cudaMalloc((void**) &dipiv, sizeof(int)*n);
-
- cudaMemcpy(da, a, sizeof(double)*n*n, cudaMemcpyHostToDevice);
- cudaMemcpy(db, b, sizeof(double)*n, cudaMemcpyHostToDevice);
-
- s = culaDeviceDgesv(n, nrhs, da, lda, dipiv, db, ldb);
- }
-