SlideShare a Scribd company logo
1 of 123
Download to read offline
第12回 GPUによる画像処理
長岡技術科学大学 電気電子情報工学専攻 出川智啓
授業項目
8. 並列計算の概念(プロセスとスレッド)
9. GPUのアーキテクチャ
10. GPGPUのプログラム構造
11. GPUでの並列プログラミング(ベクトル和)
12. GPUによる画像処理
13. GPUのメモリ階層
14. GPGPU組込開発環境
15. GPGPU開発環境(OpenCL)
GPGPU実践基礎工学2 2015/11/25
今回の内容
GPGPU実践基礎工学3
 画像処理
 ネガティブ処理,画像反転,空間フィルタ,モザイク処理
 画像処理を簡略化した1次元的な処理
 2次元的な並列処理
 2次元配列の表現
 ベクトル和
 モノクロ画像処理
2015/11/25
画像処理
GPGPU実践基礎工学4
 デジタル画像を別の画像に変換
 処理の種類
 画像の拡大・縮小
 画像の反転
 フィルタ
 2値化,ぼかしなど
2015/11/25
画像処理を行うプログラムの流れ
GPGPU実践基礎工学5
 読み込む画像を準備
 対象ファイルをオープン
 画像の読込
 画像ファイルの種類(bmp,jpg,png等)に応じて読み込む方
法を選択
 画像ファイルからヘッダ情報を読み込み,様々な情報を取得
 メモリを確保し,画素情報を読込
 定められたアルゴリズムで画像を処理
 処理された画像の出力
2015/11/25
画像処理
GPGPU実践基礎工学6
 画像を読むプログラムを作るだけで一苦労
 画像処理が主目的ではなく,GPUの使い方を学習するこ
とが目的
 画像をモノクロに限定
 プログラム中で画像に相当するデータを生成
 ターミナルにテキスト出力(横の位置,縦の位置,色情報)
 画像の表示にはgnuplotを利用
 モノクロ画像に対して簡単な処理を実行
2015/11/25
取り扱うモノクロ画像
GPGPU実践基礎工学7
 型はunsigned char
 1バイトの整数型
 取り扱える範囲は0~255
 0を黒,255を白とみなす
 1次元配列で取り扱う
 画像は2次元なので,2次元配列で取り扱う方が自然
 mallocやcudaMallocでは2次元配列を確保できない
2015/11/25
取り扱うモノクロ画像の内容
GPGPU実践基礎工学8
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,  0,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,  0,  0,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,  0,  0,  0,255,255,255,255,
255,255,255,255,255,255,255,255,255,  0,  0,  0,  0,255,255,255,
255,255,255,255,255,255,255,255,255,  0,  0,  0,  0,  0,255,255,
255,255,255,255,255,255,255,255,255,  0,  0,  0,  0,  0,  0,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
unsigned char
picture[] = {
x
y
2015/11/25
取り扱うモノクロ画像の内容
GPGPU実践基礎工学9
 gnuplotで表示
 左下を原点として表示
 画像処理では左上が原点
x
y
2015/11/25
画像処理
GPGPU実践基礎工学10
 ネガティブ処理
 反転
 水平反転,垂直反転
 空間フィルタ
 ぼかし,輪郭抽出
 モザイク処理
2015/11/25
画像処理の簡略化(1次元化)
GPGPU実践基礎工学11
 いきなり画像処理は難しい
 1次元の配列に対して,画像処理と同じような処理を実行
 どのような処理を行うかを確認
 ネガティブ処理
 水平反転
 空間フィルタ(ぼかし,輪郭抽出)
 モザイク処理
2015/11/25
原画像もどき
2015/11/25GPGPU実践基礎工学12
 幅 WIDTH=64 (0~63)
 [3*WIDTH/16,9*WIDTH/16)の範囲を白(255),それ
以外を黒(0)
 変数名
 原画像 p[]
 処理画像 filtered[]
 原画像pのピクセル値
画素値
横位置
ネガティブ処理
2015/11/25GPGPU実践基礎工学13
 色の反転処理
 黒(0)を白(255),白(255)を黒(0)に反転
 (白−各画素の値)を新しい画素の値とする
画素値
横位置
画素値
原画像p[]
処理画像
filtered[]
白(255)を黒(0)に
黒(0)を白(255)に
ネガティブ処理
2015/11/25GPGPU実践基礎工学14
 色の反転処理
 黒(0)を白(255),白(255)を黒(0)に反転
 (白−各画素の値)を新しい画素の値とする
void negative(unsigned char *p, unsigned char *filtered){
int i;
for (i = 0; i<WIDTH; i++){
filtered[i] = WHITE ‐ p[i];
}
}
水平反転
2015/11/25GPGPU実践基礎工学15
 画像の幾何的位置を反転
 水平反転 i→(WIDTH‐1)‐i
 p[i]→filtered[(WIDTH‐1)‐i]
画素値
横位置
画素値
原画像p[]
処理画像
filtered[]
横位置1の画素値を62番目の画素値に
横位置35の画素値を28番目の画素値に
水平反転
2015/11/25GPGPU実践基礎工学16
 画像の幾何的位置を反転
 水平反転 i→(WIDTH‐1)‐i
 p[i]→filtered[(WIDTH‐1)‐i]
void hreflect(unsigned char *p, unsigned char *filtered){
int i;
for (i = 0; i<WIDTH; i++){
//(WIDTH‐1)‐iは反転後の横位置
filtered[(WIDTH ‐ 1) ‐ i] = p[i];
}
}
空間フィルタ
2015/11/25GPGPU実践基礎工学17
 ある画素とその周囲の画素を使って処理
 処理の仕方を規定したフィルタカーネルを定義
 フィルタカーネルは1次元配列で表現,引数として関数に渡す
 ぼかし(平均)フィルタ
 輪郭抽出(ラプラシアン)フィルタ
1/3 1/3 1/3
1 ‐2 1
float blur[3] ={1.0f/3.0f,1.0f/3.0f,1.0f/3.0f};
float laplacian[9] ={ 1.0f,‐2.0f, 1.0f};
画素値
横位置
画素値
空間フィルタ
2015/11/25GPGPU実践基礎工学18
 ある画素とその周囲の画素を使って処理
 ある位置iの左右(i‐1,i+1)の計3画素の値を読み,それぞ
れフィルタカーネルの各値との積を計算し,合計を取った値を
処理画像のi番目の画素とする
ぼかしフィルタカーネル
1/3 1/3 1/3
255/3+255/3+255/3=255
原画像p[]
処理画像
filtered[]
画素値
横位置
画素値
空間フィルタ
2015/11/25GPGPU実践基礎工学19
 ある画素とその周囲の画素を使って処理
 ある位置iの左右(i‐1,i+1)の計3画素の値を読み,それぞ
れフィルタカーネルの各値との積を計算し,合計を取った値を
処理画像のi番目の画素とする
ぼかしフィルタカーネル
1/3 1/3 1/3
255/3+255/3+255/3=255
原画像p[]
処理画像
filtered[]
画素値
横位置
画素値
空間フィルタ
2015/11/25GPGPU実践基礎工学20
 ある画素とその周囲の画素を使って処理
 ある位置iの左右(i‐1,i+1)の計3画素の値を読み,それぞ
れフィルタカーネルの各値との積を計算し,合計を取った値を
処理画像のi番目の画素とする
ぼかしフィルタカーネル
1/3 1/3 1/3
255/3+255/3+255/3=255
原画像p[]
処理画像
filtered[]
画素値
横位置
空間フィルタ
2015/11/25GPGPU実践基礎工学21
 ある画素とその周囲の画素を使って処理
 ある位置iの左右(i‐1,i+1)の計3画素の値を読み,それぞ
れフィルタカーネルの各値との積を計算し,合計を取った値を
処理画像のi番目の画素とする
ぼかしフィルタカーネル
1/3 1/3 1/3
0/3+255/3+255/3=170
原画像p[]
処理画像
filtered[]
画素値
空間フィルタ
2015/11/25GPGPU実践基礎工学22
 ある画素とその周囲の画素を使って処理
 forループでiの値を変化させ,p[i‐1],p[i],p[i+1]の値
から処理後の画素値filtered[i]を計算
void boxfilter
(unsigned char *p, unsigned char *filtered, float *filter){
int i, result=BLACK;
for (i = 1; i<WIDTH ‐ 1; i++){//端の画素は処理をしない
result = filter[0]*p[i‐1]+filter[1]*p[i]+filter[2]*p[i+1];
//フィルタ後の値が負になれば0に切り上げ,255を超えたら255に収める
if (result<BLACK) result = 0;
if (result>WHITE) result = WHITE;
filtered[i] = (unsigned char)result;
}
}
画素値
横位置
画素値
空間フィルタ
2015/11/25GPGPU実践基礎工学23
 輪郭抽出フィルタの結果
 白と黒の境界でのみ値が255になり,それ以外では0
 両端はフィルタ処理できないため,初期値がそのまま使われる
原画像p[]
処理画像
filtered[]白と黒の境界でのみ
画素値が0より大きく
なる
モザイク処理
2015/11/25GPGPU実践基礎工学24
 画像を小領域に分け,その領域を全て同じ色に置換
 小領域内の全画素を,小領域内の画素の平均値に置換
 小領域を移動するループ内に,小領域内の画素の平均値を
計算するループを設ける
画素値
横位置
原画像p[]
処理画像
filtered[]
画素値
小領域
モザイク処理
2015/11/25GPGPU実践基礎工学25
 画像を小領域に分け,その領域を全て同じ色に置換
 小領域内の全画素を,小領域内の画素の平均値に置換
 小領域を移動するループ内に,小領域内の画素の平均値を
計算するループを設ける
画素値
横位置
原画像p[]
処理画像
filtered[]
画素値
モザイク処理
2015/11/25GPGPU実践基礎工学26
 画像を小領域に分け,その領域を全て同じ色に置換
 小領域内の全画素を,小領域内の画素の平均値に置換
 小領域を移動するループ内に,小領域内の画素の平均値を
計算するループを設ける
画素値
横位置
原画像p[]
処理画像
filtered[]
画素値
小領域
モザイク処理
2015/11/25GPGPU実践基礎工学27
 画像を小領域に分け,その領域を全て同じ色に置換
 小領域内の全画素を,小領域内の画素の平均値に置換
 小領域を移動するループ内に,小領域内の画素の平均値を
計算するループを設ける
画素値
横位置
原画像p[]
処理画像
filtered[]
画素値
モザイク処理
2015/11/25GPGPU実践基礎工学28
 画像を小さな領域に分け,その領域を全て同じ色に置換
 小領域内で画素の平均値を計算し,処理画像の小領域内の
全画素をその平均値とする
void mosaic(unsigned char *p,unsigned char *filtered,int mosaicSize){
int i,isub,average;
for (i = 0; i<WIDTH; i += mosaicSize){//小領域を移動するループ
//小領域内の画素の平均値を計算
average = 0;
for(isub = 0; isub<mosaicSize; isub++)
average += p[(i+isub)];          
average /= mosaicSize; 
//小領域内の全画素を平均値で塗りつぶす
for(isub = 0; isub<mosaicSize; isub++)
filtered[(i+isub)] = (unsigned char)average;
}
}
処理の流れ
GPGPU実践基礎工学29
 変数を宣言し,mallocでメモリを確保
 原画像を格納する変数 p
 処理後の画像を格納する変数 filtered
 原画像pを作成
 pをfilteredにコピーしておく
 処理を実行
 関数を作成し,pとfilteredを渡す
 filteredの内容を画面に出力
2015/11/25
メイン関数(CPU版)
GPGPU実践基礎工学30
#include<stdio.h>
#include<stdlib.h>
#define WHITE (255)
#define BLACK (0)
#define WIDTH  (64)
#define Nbytes (WIDTH*sizeof(unsigned char))
void create(unsigned char *);
void copy(unsigned char *,unsigned char *);
void print(unsigned char *);
void negative(unsigned char *, unsigned char *);
void hreflect(unsigned char *, unsigned char *);
void boxfilter(unsigned char *, unsigned char *, float *);
void mosaic(unsigned char *, unsigned char *, int);
int main(void){
unsigned char *p= (unsigned char *)malloc(Nbytes);
unsigned char *filtered= (unsigned char *)malloc(Nbytes);
//ここで空間フィルタのカーネルを宣言
2015/11/25
imageproc1d.c
メイン関数(CPU版)
GPGPU実践基礎工学31
create(p);
copy(p,filtered);
//ここで処理を行い,結果をfilteredに格納
//画面に各画素の値を表示
print(filtered);
return 0;
}
//画像の内容をコピー
void copy(unsigned char *src, unsigned char *dst){
int i;
for (i = 0; i<WIDTH; i++)
dst[i] = src[i];
}
//画像の内容を画面に出力
void print(unsigned char *p){
int i;
for (i = 0; i<WIDTH; i++)
printf("%d %d¥n", i, p[i]);
}
2015/11/25
imageproc1d.c
画像の作成
2015/11/25GPGPU実践基礎工学32
 [3*WIDTH/16,9*WIDTH/16)の範囲を白(255),それ
以外を黒(0)
void create(unsigned char *p){
int i, x_origin;
for (i = 0; i<WIDTH; i++)
p[i] = WHITE;
x_origin = 3 * WIDTH / 16;
for (i = 0; i<6 * WIDTH / 16; i++)
p[i + x_origin] = BLACK;
}
3WIDTH/16
画素値
横位置6WIDTH/16
結果の画面表示とファイル保存
GPGPU実践基礎工学33
 print関数が画面に各画素の座標と値を表示
 画面出力のファイル表示(出力のリダイレクトを利用)
 >を利用して保存,結果は表計算等で確認
 $ コマンド > ファイル名
0 255
1 255
:
62 255
63 255
$ ./a.out > pic.txt
$ cat pic.txt
0 255
1 255
:
62 255
63 255
2015/11/25
GPUへの移植の方針
GPGPU実践基礎工学
 現画像の作成はCPUで行い,GPUへ転送
 1スレッドが1画素の処理を実行
 forループを排除し,配列添字とスレッド番号を対応
 空間フィルタ
 端の画素の処理ができないので今回は処理しない
 モザイク
 領域の大きさは1ブロックと同じとする
 領域内の画素の平均値の計算は非常に難易度が高い
 各ブロックにおけるthreadIdx.x=0のスレッドが平均を計算して処
理画像に書き込む
34 2015/11/25
メイン関数(GPU版)
GPGPU実践基礎工学35
#include<stdio.h>
#include<stdlib.h>
#define WHITE (255)
#define BLACK (0)
#define WIDTH  (64)
#define Nbytes (WIDTH*sizeof(unsigned char))
#define THREAD 16
#define BLOCK (WIDTH/THREAD)
void create(unsigned char *);
void print(unsigned char *);
int main(void){
unsigned char *p= (unsigned char *)malloc(Nbytes);
unsigned char *dev_p, *dev_filtered;
cudaMalloc( (void **)&dev_p, Nbytes);
cudaMalloc( (void **)&dev_filtered, Nbytes);
2015/11/25
imageproc1d.cu
メイン関数(GPU版)
GPGPU実践基礎工学36
//ここで空間フィルタのカーネルを宣言
float *filter;
cudaMalloc( (void **)&filter, sizeof(float)*3);
cudaMemcpy(filter, フィルタのカーネル, sizeof(float)*3, cudaMemcpyHostToDevice);
create(p); //CPUで画像を生成してGPUへ送った後,変数dev_filteredにコピーしておく
cudaMemcpy(dev_p, p, Nbytes, cudaMemcpyHostToDevice);
cudaMemcpy(dev_filtered, dev_p, Nbytes, cudaMemcpyDeviceToDevice);
//ここで処理を行い,結果をdev_filteredに格納
//dev_filteredの内容をCPUへ送る
unsigned char *filtered = (unsigned char *)malloc(Nbytes);
cudaMemcpy(filtered, dev_filtered, Nbytes, cudaMemcpyDeviceToHost);
free(p);
free(filtered);
cudaFree(dev_p);
cudaFree(dev_filtered);
cudaFree(filter);
2015/11/25
imageproc1d.cu
メイン関数(GPU版)
GPGPU実践基礎工学37
return 0;
}
//原画像の生成
void create(unsigned char *p){
int i, x_origin;
for (i = 0; i<WIDTH; i++)
p[i] = WHITE;
x_origin = 3 * WIDTH / 16;
for (i = 0; i<6 * WIDTH / 16; i++)
p[i + x_origin] = BLACK;
}
//画像の内容を画面に出力
void print(unsigned char *p){
int i;
for (i = 0; i<WIDTH; i++)
printf("%d %d¥n", i, p[i]);
}
2015/11/25
imageproc1d.cu
ネガティブ処理
2015/11/25GPGPU実践基礎工学38
 1スレッドが1画素の値を計算
 ベクトル和のようにスレッド番号と配列添字の対応を計算
画素値
横位置
画素値
原画像p[]
処理画像
filtered[]
・・・0 1 2 3スレッド番号
void negative(unsigned char *p, unsigned char *filtered){
int i;
for (i = 0; i<WIDTH; i++)
filtered[i] = WHITE ‐ p[i];
}
ネガティブ処理
GPGPU実践基礎工学39 2015/11/25
imageproc1d.c
__global__ void negative(unsigned char *p, unsigned char *filtered){
int i;
i = blockIdx.x*blockDim.x + threadIdx.x; //スレッド数と配列添字の対応
filtered[i] = WHITE ‐ p[i];
}
ネガティブ処理
GPGPU実践基礎工学40 2015/11/25
imageproc1d.cu
水平反転
2015/11/25GPGPU実践基礎工学41
 1スレッドが1画素の値を反転
 ベクトル和のようにスレッド番号と配列添字の対応を計算
 書込先が変わる
画素値
横位置
画素値
原画像p[]
処理画像
filtered[]
横位置35の画素値を28番目の画素値に
0 1 2 3 ・・・スレッド番号
void hreflect(unsigned char *p, unsigned char *filtered){
int i;
for (i = 0; i<WIDTH; i++)
//(WIDTH‐1)‐iは反転後の横位置
filtered[(WIDTH ‐ 1) ‐ i] = p[i];
}
水平反転
GPGPU実践基礎工学42 2015/11/25
imageproc1d.c
__global__ void hreflect(unsigned char *p, unsigned char *filtered){
int i;
i = blockIdx.x*blockDim.x + threadIdx.x;
//(WIDTH‐1)‐iは反転後の横位置
filtered[(WIDTH‐1)‐i] = p[i];
}
水平反転
GPGPU実践基礎工学43 2015/11/25
imageproc1d.cu
空間フィルタ
2015/11/25GPGPU実践基礎工学44
 1スレッドが1画素の値を計算
 ある位置iの画素だけではなく左右(i‐1,i+1)の画素も参照
 全スレッドが同じフィルタカーネルを参照
画素値
横位置
画素値
ぼかしフィルタカーネル
原画像p[]
処理画像
filtered[]
0 1 2 3スレッド番号
1/3 1/3 1/3
・・・
void boxfilter
(unsigned char *p, unsigned char *filtered, float *filter){
int i, result=BLACK;
for (i = 1; i<WIDTH ‐ 1; i++){//端の画素は処理をしない
result = filter[0]*p[i‐1]+filter[1]*p[i]+filter[2]*p[i+1];
//フィルタ後の値が負になれば0に切り上げ,255を超えたら255に収める
if (result<BLACK) result = 0;
if (result>WHITE) result = WHITE;
filtered[i] = (unsigned char)result;
}
}
空間フィルタ
GPGPU実践基礎工学45 2015/11/25
imageproc1d.c
__global__ void boxfilter
(unsigned char *p, unsigned char *filtered, float *filter){
int i, result = BLACK;
i = blockIdx.x*blockDim.x + threadIdx.x;
if(0<i && i<WIDTH‐1) //端の画素は処理をしないため,ifで処理を分岐
result = filter[0]*p[i‐1]+filter[1]*p[i]+filter[2]*p[i+1];
//フィルタ後の値が負になれば0に切り上げ,255を超えたら255に収める
if(result<BLACK) result = 0;
if(result>WHITE) result = WHITE;
filtered[i]  = (unsigned char)result;
}
空間フィルタ
GPGPU実践基礎工学46 2015/11/25
imageproc1d.cu
モザイク処理
2015/11/25GPGPU実践基礎工学47
 1ブロック内の1スレッドのみが処理
 1スレッドがブロック内の全画素の平均を計算
 平均の画素値を処理画像に書込
画素値
横位置
原画像p[]
処理画像
filtered[]
画素値
スレッド番号 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 ・・・
void mosaic(unsigned char *p,unsigned char *filtered,int mosaicSize){
int i,isub,average;
for (i = 0; i<WIDTH; i += mosaicSize){//小領域を移動するループ
//小領域内の画素の平均値を計算
average = 0;
for(isub = 0; isub<mosaicSize; isub++)
average += p[(i+isub)];          
average /= mosaicSize; 
//小領域内の全画素を平均値で塗りつぶす
for(isub = 0; isub<mosaicSize; isub++)
filtered[(i+isub)] = (unsigned char)average;
}
}
モザイク処理
GPGPU実践基礎工学48 2015/11/25
imageproc1d.c
__global__ void mosaic
(unsigned char *p, unsigned char *filtered, int mosaicSize){
int i,isub,average;
i = blockIdx.x*blockDim.x + threadIdx.x;
if(threadIdx.x == 0){//ブロック内の1スレッドのみが処理
//小領域内の画素の平均値を計算
average = 0;
for(isub = 0; isub<mosaicSize; isub++)
average += p[(i+isub)];
average /= mosaicSize;
//小領域内の全画素を平均値で塗りつぶす
for(isub = 0; isub<mosaicSize; isub++)
filtered[(i+isub)] = (unsigned char)average;
}
}
モザイク処理
GPGPU実践基礎工学49 2015/11/25
imageproc1d.cu
ネガティブ処理
2015/11/25GPGPU実践基礎工学50
 色の反転処理
 黒を白,白を黒に反転
原画像 処理画像
画像反転
2015/11/25GPGPU実践基礎工学51
 画像の幾何的位置を反転
 画像(画素)の配列添字を変えて出力
原画像 処理画像
空間フィルタ
2015/11/25GPGPU実践基礎工学52
 ある画素とその周囲の画素を使って処理
 処理の仕方を規定したカーネルを定義
 カーネルを変更することで様々な処理が可能
原画像 輪郭抽出
原画像 輪郭抽出
フィルタ処理
2015/11/25GPGPU実践基礎工学53
 2次元的な処理
 あるピクセルの周囲情報を利用して効果を計算
 画像を矩形領域で分割した2次元的な並列処理が自然
0 1 0
1 ‐4 1
0 1 0
= b+d‐4e+f+h
フィルタ
(カーネル)
a b c
d e f
g h i
モザイク処理
2015/11/25GPGPU実践基礎工学54
 画像を小さな領域に分け,その領域を全て同じ色に置換
 領域内のある1画素の値か,領域内の画素の平均値にするこ
とが多い
原画像 処理画像
2次元配列
GPGPU実践基礎工学55
 変数名の後ろに[]を2個付けて宣言
 1次元配列はベクトル,2次元配列は行列や画像
unsigned char picture[Nx][Ny];
vector[Nx]
Nx=8
i
Nx=8
j
i
matrix[Nx][Ny]
Ny=8
2015/11/25
2次元配列の1次元配列表現
2015/11/25GPGPU実践基礎工学56
 mallocやcudaMallocは1次元配列を宣言
 2次元配列を宣言できない
 1次元配列を宣言し,2次元配列的に読み書き
 アドレス空間は1次元
 2次元配列でも1次元のアドレスで表現
 1次元目が連続か,2次元目が連続かが言語によって異なる
j
i
j
i
1次元目が連続
matrix[Nx][Ny] matrix[Nx][Ny]
2次元目が連続
2次元配列の1次元配列表現
2015/11/25GPGPU実践基礎工学57
 C言語は2次元目が連続
 2次元配列の場合
 1次元配列の場合
picutre[1][2] = 11
picture[_______] = 11
Nx=8
1*8 + 2
picture[i][j]  picture[i*Ny+j]
j
i
1
2
3
4
5
9
10
11
12
6
7
8
picture[Nx][Ny]
Ny=8
ベクトル和C=A+B(2次元版)
2015/11/25GPGPU実践基礎工学58
 1次元のベクトル和とほぼ同じ
 並列化が容易
 for文の書く順番で実行速度が変化
c[][] a[][] b[][]
#define Nx (1024)
#define Ny (1024)
void init(float a[Nx][Ny], float b[Nx][Ny],
float c[Nx][Ny]){
int i,j;
//iとjのループを入れ替えるとどうなるか?
for(i=0;i<Nx;i++){
for(j=0;j<Nx;j++){
a[i][j] = 1.0;
b[i][j] = 2.0;
c[i][j] = 0.0;
}
}
}
void add(float a[Nx][Ny], float b[Nx][Ny],
float c[Nx][Ny]){
int i,j;
//iとjのループを入れ替えるとどうなるか?
for(i=0;i<Nx;i++){
for(j=0;j<Nx;j++){
c[i][j] = a[i][j]+b[i][j];
}
}
}
int main(void){
float a[Nx][Ny],b[Nx][Ny],c[Nx][Ny];
init(a, b, c);
add(a, b, c);
return 0;
}
ベクトル和(2次元版)
2015/11/25GPGPU実践基礎工学59
vectoradd2d.c
#include<stdlib.h>
#define Nx (1024)
#define Ny (1024)
#define Nbytes (Nx*Ny*sizeof(float))
void init(float *a, float *b, float *c){
int i,j,ij;
for(i=0;i<Nx;i++){
for(j=0;j<Ny;j++){
ij = i*Ny+j;
//ij = i+Nx*j;にするとどうなるか?
a[ij] = 1.0;
b[ij] = 2.0;
c[ij] = 0.0;
}
}
}
void add(float *a, float *b, float *c){
int i,j,ij;
for(i=0;i<Nx;i++){
for(j=0;j<Ny;j++){
ij = i*Ny+j;
//ij = i+Nx*j;にするとどうなるか?
c[ij] = a[ij]+b[ij];
}
}
}
int main(void){
float *a,*b,*c;
a = (float *)malloc(Nbytes);
b = (float *)malloc(Nbytes);
c = (float *)malloc(Nbytes);
init(a, b, c);
add(a, b, c);
free(a);
free(b);
free(c);
return 0;
}
ベクトル和(2次元→1次元版)
2015/11/25GPGPU実践基礎工学60
vectoradd2d_1darray.c
GPUによる2次元的な並列処理
2015/11/25GPGPU実践基礎工学61
 ブロックとスレッドを2次元的に設定
 1スレッドが配列の1要素(画像の1ピクセル)を処理
 スレッドを2次元的に配置してブロックを構成
GPUの並列化の階層
 グリッド-ブロック-スレッドの3階層
 各階層の情報を参照できる変数
 x,y,zをメンバにもつdim3型構造体
 グリッド(Grid)
 gridDim グリッド内にあるブロックの数
 ブロック(Block)
 blockIdx ブロックに割り当てられた番号
 blockDim ブロック内にあるスレッドの数
 スレッド(Thread)
 threadIdx スレッドに割り当てられた番号
GPGPU実践基礎工学62 2015/11/25
Hello Threads(2次元版)
 <<< , >>>の中にどのように数字を書くか
2015/11/25GPGPU実践基礎工学63
#include<stdio.h>
__global__ void hello(){
printf("gridDim.x=%d,blockIdx.x=%d,blockDim.x=%d,threadIdx.x=%d¥n",
gridDim.x, blockIdx.x, blockDim.x, threadIdx.x);
printf("gridDim.y=%d,blockIdx.y=%d,blockDim.y=%d,threadIdx.y=%d¥n",
gridDim.y, blockIdx.y, blockDim.y, threadIdx.y);
}
int main(void){
hello<<<?,?>>>();
cudaDeviceSynchronize();
return 0;
}
hellothreads2d.cu
Hello Threads(2次元版)
 1次元と同様<<<2,4>>>等として実行
 実行結果(画面出力)
2015/11/25GPGPU実践基礎工学64
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=0
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=1
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=2
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=3
gridDim.x=2, blockIdx.x=1, blockDim.x=4, threadIdx.x=0
gridDim.x=2, blockIdx.x=1, blockDim.x=4, threadIdx.x=1
gridDim.x=2, blockIdx.x=1, blockDim.x=4, threadIdx.x=2
gridDim.x=2, blockIdx.x=1, blockDim.x=4, threadIdx.x=3
gridDim.y=1, blockIdx.y=0, blockDim.y=1, threadIdx.y=0
gridDim.y=1, blockIdx.y=0, blockDim.y=1, threadIdx.y=0
gridDim.y=1, blockIdx.y=0, blockDim.y=1, threadIdx.y=0
gridDim.y=1, blockIdx.y=0, blockDim.y=1, threadIdx.y=0
gridDim.y=1, blockIdx.y=0, blockDim.y=1, threadIdx.y=0
gridDim.y=1, blockIdx.y=0, blockDim.y=1, threadIdx.y=0
gridDim.y=1, blockIdx.y=0, blockDim.y=1, threadIdx.y=0
gridDim.y=1, blockIdx.y=0, blockDim.y=1, threadIdx.y=0
並列度の指定が
できていない
2次元的な並列度の指定
2015/11/25GPGPU実践基礎工学65
 <<<,>>>の中にどのように数字を書くか
 1次元の場合は数字を書くことができた
 2次元,3次元は数字を並べて書くことができない
 dim3型構造体を利用
int main(void){
dim3 block(2,4,1), thread(4,2,1);
hello<<<block, thread>>>();
hello<<<dim3(2,4,1), dim3(4,2,1)>>>(...);
}
dim3型変数block, 
threadを利用
・・・
あるいは直接dim3型として記述・・・
Hello Threads(2次元版)
 実行結果(画面出力)
2015/11/25GPGPU実践基礎工学66
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=0
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=1
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=2
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=3
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=0
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=1
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=2
gridDim.x=2, blockIdx.x=0, blockDim.x=4, threadIdx.x=3
:(中略)
gridDim.y=4, blockIdx.y=0, blockDim.y=2, threadIdx.y=0
gridDim.y=4, blockIdx.y=0, blockDim.y=2, threadIdx.y=0
gridDim.y=4, blockIdx.y=0, blockDim.y=2, threadIdx.y=0
gridDim.y=4, blockIdx.y=0, blockDim.y=2, threadIdx.y=0
gridDim.y=4, blockIdx.y=0, blockDim.y=2, threadIdx.y=1
gridDim.y=4, blockIdx.y=0, blockDim.y=2, threadIdx.y=1
gridDim.y=4, blockIdx.y=0, blockDim.y=2, threadIdx.y=1
gridDim.y=4, blockIdx.y=0, blockDim.y=2, threadIdx.y=1
:
対応
対応
各スレッドが異なるi,jを参照するには
 CUDAでは並列化に階層がある
 全体の領域(グリッド)をブロックに分割
 ブロックの中をスレッドに分割
<<<dim3(2,4,1), dim3(4,2,1)>>>
ブロックの数 1ブロックあたりの
スレッドの数
x方向ブロック数×1ブロックあたりのスレッドの数
×y方向ブロック数×1ブロックあたりのスレッドの数=総スレッド数
GPGPU実践基礎工学67 2015/11/25
総スレッド数=2×4×4×2=64
各スレッドが異なるi,jを参照するには
2015/11/25GPGPU実践基礎工学68
 Nx=8, Ny=8, x,y方向スレッド数4,ブロック数2
 gridDim.x=2, gridDim.y=2
 blockDim.x=4,blockDim.y=4
(0,0)(1,0)(2,0)(3,0)(0,0)
(3,3) (3,3)
(0,1)(1,1)(2,1)(3,1)
(0,2)(1,2)(2,2)(3,2)
(0,3)(1,3)(2,3)(3,3) (3,3)
(0,0) (0,0)
threadIdx.x,threadIdx.y
i= 0 1 2 3 4 5 6 7
j=01234567
・・・
・・・
・・・
・・・
・・・
・・・
(0,0)(1,0)(2,0)(3,0)(0,0)
(3,3) (3,3)
(0,1)(1,1)(2,1)(3,1)
(0,2)(1,2)(2,2)(3,2)
(0,3)(1,3)(2,3)(3,3) (3,3)
(0,0) (0,0)
各スレッドが異なるi,jを参照するには
2015/11/25GPGPU実践基礎工学69
 Nx=8, Ny=8, x,y方向スレッド数4,ブロック数2
blockDim.x=4
blockDim.y=4
threadIdx.x,threadIdx.y
blockIdx.x=0 blockIdx.x=1
blockIdx.y=0blockIdx.y=1
gridDim.x=2
gridDim.y=2
各スレッドが異なるi,jを参照するには
2015/11/25GPGPU実践基礎工学70
 Nx=8, Ny=8, x,y方向スレッド数4,ブロック数2
 i = blockIdx.x*blockDim.x + threadIdx.x
 j = blockIdx.y*blockDim.y + threadIdx.y
(0,0)(1,0)(2,0)(3,0)(0,0)
(3,3) (3,3)
(0,1)(1,1)(2,1)(3,1)
(0,2)(1,2)(2,2)(3,2)
(0,3)(1,3)(2,3)(3,3) (3,3)
(0,0) (0,0)
block(0,0) block(1,0)
block(0,1) block(1,1)
i= 0 1 2 3 4 5 6 7
j=01234567
threadIdx.x,threadIdx.y
#include<stdlib.h>
#define Nx (1024)
#define Ny (1024)
#define Nbytes (Nx*Ny*sizeof(float))
void init(float *a, float *b, float *c){
int i,j,ij;
for(i=0;i<Nx;i++){
for(j=0;j<Ny;j++){
ij = i*Ny+j;
a[ij] = 1.0;
b[ij] = 2.0;
c[ij] = 0.0;
}
}
}
void add(float *a, float *b, float *c){
int i,j,ij;
for(i=0;i<Nx;i++){
for(j=0;j<Ny;j++){
ij = i*Ny+j;
c[ij] = a[ij]+b[ij];
}
}
}
int main(void){
float *a,*b,*c;
a = (float *)malloc(Nbytes);
b = (float *)malloc(Nbytes);
c = (float *)malloc(Nbytes);
init(a, b, c);
add(a, b, c);
free(a);
free(b);
free(c);
return 0;
}
ベクトル和(1次元配列版)
2015/11/25GPGPU実践基礎工学71
vectoradd2d_1darray.c
#define Nx (1024)
#define Ny (1024)
#define Nbytes (Nx*Ny*sizeof(float))
#define NTx (16)
#define NTy (16)
#define NBx (Nx/NTx)
#define NBy (Ny/NTy)
__global__ void init(float *a, float *b,
float *c){
int i = blockIdx.x*blockDim.x + threadIdx.x;
int j = blockIdx.y*blockDim.y + threadIdx.y;
int ij = i*Ny + j;
a[ij] = 1.0;
b[ij] = 2.0;
c[ij] = 0.0;
}
__global__ void add(float *a, float *b,
float *c){
int i = blockIdx.x*blockDim.x + threadIdx.x;
int j = blockIdx.y*blockDim.y + threadIdx.y;
int ij = i*Ny + j;
c[ij] = a[ij] + b[ij];
}
int main(void){
float *a,*b,*c;
dim3 thread(NTx, NTy, 1);
dim3  block(NBx, NBy, 1);
cudaMalloc( (void **)&a, Nbytes);
cudaMalloc( (void **)&b, Nbytes);
cudaMalloc( (void **)&c, Nbytes);
init<<< block, thread >>>(a,b,c);
add<<< block, thread >>>(a,b,c);
cudaFree(a);
cudaFree(b);
cudaFree(c);
return 0;
}
ベクトル和(2次元並列版)
2015/11/25GPGPU実践基礎工学72
vectoradd2d.cu
実行結果
GPGPU実践基礎工学73
 2次元版
カーネル スレッド数 実行時間[s]
init 16×16 735
add 16×16 298
2015/11/25
# CUDA_PROFILE_LOG_VERSION 2.0
# CUDA_DEVICE 0 Tesla M2050
# TIMESTAMPFACTOR fffff5f7a904f250
method,gputime,cputime,occupancy
method=[ _Z4initPfS_S_ ] gputime=[ 735.072 ] cputime=[ 16.000 ] 
occupancy=[ 1.000 ]
method=[ _Z3addPfS_S_ ] gputime=[ 298.080 ] cputime=[ 7.000 ] occupancy=[ 1.000 ]
実行結果
GPGPU実践基礎工学74
 1次元版(vectoradd.cu)
カーネル スレッド数 実行時間[s]
init 256(=16×16) 109
add 256(=16×16) 113
# CUDA_PROFILE_LOG_VERSION 2.0
# CUDA_DEVICE 0 Tesla M2050
# TIMESTAMPFACTOR fffff5f7dad0bb38
method,gputime,cputime,occupancy
method=[ _Z4initPfS_S_ ] gputime=[ 108.928 ] cputime=[ 15.000 ] 
occupancy=[ 1.000 ]
method=[ _Z3addPfS_S_ ] gputime=[ 112.992 ] cputime=[ 7.000 ] occupancy=[ 1.000 ]
2015/11/25
ベクトル和(2次元並列版)の実行結果
GPGPU実践基礎工学75
 実行結果
 1次元版と比較して実行時間がかかる
 initで7倍
 addで3倍
 遅くなる要因は?
 2次元は添字iだけでなくjも計算
 添字の計算負荷は軽い
 実行時の並列度の指定
2015/11/25
#define Nx (1024)
#define Ny (1024)
#define Nbytes (Nx*Ny*sizeof(float))
#define NTx (16)
#define NTy (16)
#define NBx (Nx/NTx)
#define NBy (Ny/NTy)
__global__ void init(float *a, float *b,
float *c){
int i = blockIdx.x*blockDim.x + threadIdx.x;
int j = blockIdx.y*blockDim.y + threadIdx.y;
int ij = i+ Nx*j;
a[ij] = 1.0;
b[ij] = 2.0;
c[ij] = 0.0;
}
__global__ void add(float *a, float *b,
float *c){
int i = blockIdx.x*blockDim.x + threadIdx.x;
int j = blockIdx.y*blockDim.y + threadIdx.y;
int ij = i+ Nx*j;
c[ij] = a[ij] + b[ij];
}
int main(void){
float *a,*b,*c;
dim3 thread(NTx, NTy, 1);
dim3  block(NBx, NBy, 1);
cudaMalloc( (void **)&a, Nbytes);
cudaMalloc( (void **)&b, Nbytes);
cudaMalloc( (void **)&c, Nbytes);
init<<< block, thread >>>(a,b,c);
add<<< block, thread >>>(a,b,c);
cudaFree(a);
cudaFree(b);
cudaFree(c);
return 0;
}
ベクトル和(2次元並列版)
2015/11/25GPGPU実践基礎工学76
vectoradd2d.cu
実行結果
GPGPU実践基礎工学77
 2次元版
カーネル スレッド数 実行時間[s]
init 16×16 230
add 16×16 153
# CUDA_PROFILE_LOG_VERSION 2.0
# CUDA_DEVICE 0 Tesla M2050
# TIMESTAMPFACTOR fffff5f8098b61e0
method,gputime,cputime,occupancy
method=[ _Z4initPfS_S_ ] gputime=[ 230.976 ] cputime=[ 15.000 ] 
occupancy=[ 1.000 ]
method=[ _Z3addPfS_S_ ] gputime=[ 152.960 ] cputime=[ 6.000 ] occupancy=[ 1.000 ]
2015/11/25
2次元的な配列アクセスの優先方向(C言語)
2015/11/25GPGPU実践基礎工学78
 2次元配列の場合
in[][],out[][]
Nx
Ny
j
i
for(i=0;i<Nx;i++)
for(j=0;j<Ny;j++)
out[i][j]=in[i][j];
for(j=0;j<Ny;j++)
for(i=0;i<Nx;i++)
out[i][j]=in[i][j];
2次元的な配列アクセスの優先方向(C言語)
2015/11/25GPGPU実践基礎工学79
 2次元配列の場合
for(i=0;i<Nx;i++)
for(j=0;j<Ny;j++)
out[i][j]=in[i][j];
in[][],out[][]
Nx
Ny
j
i
for(j=0;j<Ny;j++)
for(i=0;i<Nx;i++)
out[i][j]=in[i][j];
2次元的な配列アクセスの優先方向(C言語)
2015/11/25GPGPU実践基礎工学80
 2次元配列の1次元配列的表現
for(i=0;i<Nx;i++)
for(j=0;j<Ny;j++)
out[i][j]=in[i][j];
in[],out[]
Nx
Ny
j
i
for(i=0;i<Nx;i++)
for(j=0;j<Ny;j++)
out[i*Ny+j]=
in[i*Ny+j];
2次元的な配列アクセスの優先方向
2015/11/25GPGPU実践基礎工学81
 CUDAで2次元的に並列化してアクセスする場合
i = blockIdx.x*blockDim.x
+ threadIdx.x;
j = blockIdx.y*blockDim.y
+ threadIdx.y;
out[i+Nx*j]=in[i+Nx*j];
in[],out[]
Nx
Ny
j
i
for(i=0;i<Nx;i++)
for(j=0;j<Ny;j++)
out[i*Ny+j]=
in[i*Ny+j];
threadIdx.x
threadIdx.y
2次元的な配列アクセスの優先方向
GPGPU実践基礎工学82
 C言語
 メモリアドレスは2次元目が連続
 その関係を維持するように配列を1次元化
 CUDA C
 メモリアクセスの際はthreadIdx.xが連続なアドレスにアク
セスする方が高速
 CUDA Cで2次元的な処理を行うとき
 1次元配列は1次元目のメモリアドレスが連続となるように扱っ
た方がよい
2015/11/25
2次元配列の1次元表現(C言語)
2015/11/25GPGPU実践基礎工学83
 C言語は2次元目が連続
 その関係を維持するように1次元化
 2次元配列の場合
 1次元配列の場合
picutre[1][2] = 11
picture[_______] = 11
Nx=8
1*8 + 2
picture[i][j]  picture[i*Ny+j]
j
i
1
2
3
4
5
9
10
11
12
6
7
8
picture[Nx*Ny]
Ny=8
メモリが連続な方向
2次元配列の1次元表現(CUDA C)
2015/11/25GPGPU実践基礎工学84
 メモリアクセスの際はthreadIdx.xが連続なアドレスに
アクセスする方が高速
 2次元配列の場合
 1次元配列の場合
picutre[1][2] = 11
Nx=8
j
i
1
2
3
4
5
9
10
11
12
6
7
8
picture[Nx*Ny]
Ny=8
2次元配列の1次元表現(CUDA C)
2015/11/25GPGPU実践基礎工学85
 threadIdx.xが連続なアドレスにアクセスする方がメモ
リアクセスが高速
 2次元配列の場合
 1次元配列の場合
picutre[1][2] = 11
picture[_______] = 111 + 8*2
picture[i][j]  picture[i+Nx*j]
1
2
3
4
5
9
10
11
12
6
7
8
block(1,0)
threadIdx.y
threadIdx.x
block(0,0)
block(1,1)block(0,1)
メモリが連続な方向
想定されるカーネル
 1スレッドが2次元配列の1要素を計算
 添字 i,j の要素を担当
2015/11/25GPGPU実践基礎工学86
#define Nx (1920) //水平方向ピクセル数
#define Ny (1080) //垂直方向ピクセル数
__global__ void filter(...){
int i = blockIdx.x*blockDim.x + threadIdx.x;
int j = blockIdx.y*blockDim.y + threadIdx.y;
picture[i + Nx*j] = ...;
}
画像処理の流れ
GPGPU実践基礎工学87
 変数を宣言し,mallocでメモリを確保
 画像を格納する変数 p
 処理後の画像を格納する変数 filtered
 画像pを作成
 pをfilteredにコピーしておく
 処理を実行
 関数を作成し,pとfilteredを渡す
 filteredの内容を画面に出力
2015/11/25
メイン関数(CPU版)
GPGPU実践基礎工学88
#include<stdio.h>
#include<stdlib.h>
#define WHITE (255)
#define BLACK (0)
#define WIDTH  128
#define HEIGHT WIDTH
#define Nbytes (WIDTH*HEIGHT*sizeof(unsigned char))
void create(unsigned char *);
void copy(unsigned char *,unsigned char *);
void print(unsigned char *);
int main(void){
unsigned char *p= (unsigned char *)malloc(Nbytes);
unsigned char *filtered= (unsigned char *)malloc(Nbytes);
//ここで空間フィルタのカーネルを宣言
create(p);
copy(p,filtered);
//ここで処理を行い,結果をfilteredに格納
2015/11/25
imageproc.c
メイン関数(CPU版)
GPGPU実践基礎工学89
//画面に各画素の値を表示
print(filtered);
return 0;
}
//画像の内容をコピー
void copy(unsigned char *src, unsigned char *dst){
int i;
for(i=0;i<WIDTH*HEIGHT;i++)
dst[i] = src[i];
}
//画像の内容を画面に出力(gnuplotで表示する用)
void print(unsigned char *p){
int i,j;
for(j=0;j<HEIGHT;j++){
for(i=0;i<WIDTH;i++){
printf("%d %d %d¥n", 
i, j, p[i+WIDTH*j]);//横位置,縦位置,画像の色情報
}
printf("¥n");//1行分表示したら改行を入れる(gnuplotで必要)
}
}
2015/11/25
imageproc.c
画像の作成
GPGPU実践基礎工学90
void create(unsigned char *p){
int i,j;
int x_origin,y_origin;
for(j=0;j<HEIGHT;j++){
for(i=0;i<WIDTH;i++){
p[i+WIDTH*j] = WHITE;
}
}
x_origin = 9*WIDTH/16;
y_origin = 9*HEIGHT/16;
for(i=0;i<6*WIDTH/16;i++)
for(j=i;j<6*HEIGHT/16;j++)
p[i+x_origin + WIDTH*(j+y_origin)] 
= BLACK;
} WIDTH
HEIGHT
9WIDTH/16
9HEIGHT/16
6WIDTH/16
6HEIGHT/16
2015/11/25
結果の画面表示とファイル保存
GPGPU実践基礎工学91
 print関数が画面に各画素の座標と値を表示
 画面出力のファイル表示(出力のリダイレクトを利用)
 >を利用して保存
 $ コマンド > ファイル名
0 0 255
1 0 255
:
126 127 255
127 127 255
$ ./a.out > pic.txt
$ cat pic.txt
0 0 255
1 0 255
:
126 127 255
127 127 255
2015/11/25
gnuplotによる結果の表示
GPGPU実践基礎工学92
 2次元,3次元データをプロットするアプリケーション
 コマンドラインで命令を実行してグラフを描画
 関数の描画,ファイルから読み込んだデータの表示が可能
 tesla??では正しく動作しないため,grouseで実行する
こと
2015/11/25
gnuplotによる結果の表示
2015/11/25GPGPU実践基礎工学93
 表示可能なファイルフォーマット
 データはスペース区切り
 3次元表示では列(または行)の区切りとして空白行が必要
0 0 255
1 0 255
...
126 0 255
127 0 255
<‐改行
0 1 255
1 1 255
...
126 1 255
127 1 255
<‐改行
0 2 255
1 2 255
gnuplotによる結果の表示
2015/11/25GPGPU実践基礎工学94
 実行する命令
#表示設定(画像っぽく表示するための設定)
set xrange[0:127]  #x軸の表示範囲を0~127(画像サイズ)に固定
set yrange[0:127] #y軸の表示範囲を0~127(画像サイズ)に固定
set cbrange[0:255] #カラーバーの範囲を0~255に固定
set size square #画像を正方形で表示
set pm3d map #カラー表示して真上から表示
set palette define(0"black",255"white") #0を黒,255を白
#設定を反映してファイルを読み込み
#(ファイル名はシングルクオートで囲む)
splot 'pic.txt'
plot.txt
画像処理
GPGPU実践基礎工学
 比較的簡単な4種類の処理を実装
 ネガティブ処理
 画像反転
 水平反転,垂直反転
 空間フィルタ
 ぼかし,輪郭抽出
 モザイク処理
95 2015/11/25
ネガティブ処理
2015/11/25GPGPU実践基礎工学96
 色の反転処理
 黒(0)を白(255),白(255)を黒(0)に反転
 (255−各画素の値)を新しい画素の値とする
原画像 処理画像
void negative(unsigned char *p, unsigned char *filtered){
int i,j;
for(j=0;j<HEIGHT;j++){
for(i=0;i<WIDTH;i++){
filtered[i+WIDTH*j] = WHITE ‐ p[i + WIDTH*j];
}
}
}
ネガティブ処理
GPGPU実践基礎工学97 2015/11/25
imageproc.c
水平反転
2015/11/25GPGPU実践基礎工学98
 画像の幾何的位置を反転
 水平反転 i→(WIDTH‐1)‐i
 垂直反転 j→(HEIGHT‐1)‐j 
原画像 処理画像
j
HEIGHT‐1
i0 WIDTH‐1
垂直反転
2015/11/25GPGPU実践基礎工学99
 画像の幾何的位置を反転
 水平反転 i→(WIDTH‐1)‐i
 垂直反転 j→(HEIGHT‐1)‐j 
原画像 処理画像
j
HEIGHT‐1
i0 WIDTH‐1
void hreflect(unsigned char *p, unsigned char *reflected){
int i,j,iref;
for(j=0;j<HEIGHT;j++){
for(i=0;i<WIDTH;i++){
iref = (WIDTH‐1)‐i; //反転後のx座標値
reflected[iref+WIDTH*j] = p[i + WIDTH*j];
}
}
}
水平反転
GPGPU実践基礎工学100 2015/11/25
imageproc.c
void vreflect(unsigned char *p, unsigned char *reflected){
int i,j,jref;
for(j=0;j<HEIGHT;j++){
for(i=0;i<WIDTH;i++){
jref = (HEIGHT‐1)‐j; //反転後のy座標値
reflected[i+WIDTH*jref] = p[i + WIDTH*j];
}
}
}
垂直反転
GPGPU実践基礎工学101 2015/11/25
imageproc.c
空間フィルタ
2015/11/25GPGPU実践基礎工学102
 ある画素とその周囲の画素を使って処理
 処理の仕方を規定したカーネルを定義
 カーネルは1次元配列で表現
原画像 輪郭抽出
0 1 0
1 ‐4 1
0 1 0
= b+d‐4e+f+h
フィルタ
(カーネル)
a b c
d e f
g h i
空間フィルタ
GPGPU実践基礎工学103
 カーネルは1次元配列で表現し,引数で渡す
 ぼかし(平均フィルタ)
 輪郭抽出(ラプラシアンフィルタ)
1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9
0 1 0
1 ‐4 1
0 1 0
float blur[9] ={1.0f/9.0f,1.0f/9.0f,1.0f/9.0f,
1.0f/9.0f,1.0f/9.0f,1.0f/9.0f,
1.0f/9.0f,1.0f/9.0f,1.0f/9.0f};
float laplacian[9] ={ 0.0f, 1.0f, 0.0f,
1.0f,‐4.0f, 1.0f,
0.0f, 1.0f, 0.0f};
2015/11/25
void boxfilter(unsigned char *p, unsigned char *filtered, float *filter){
int i,j
int result = BLACK;
//端では何もしない
for(j=1;j<HEIGHT‐1;j++){
for(i=1;i<WIDTH‐1;i++){
result =  filter[0]*p[(i‐1) + WIDTH*(j‐1)]
+filter[1]*p[(i ) + WIDTH*(j‐1)]
+filter[2]*p[(i+1) + WIDTH*(j‐1)]
+filter[3]*p[(i‐1) + WIDTH*(j  )]
+filter[4]*p[(i ) + WIDTH*(j  )]
+filter[5]*p[(i+1) + WIDTH*(j  )]
+filter[6]*p[(i‐1) + WIDTH*(j+1)]
+filter[7]*p[(i ) + WIDTH*(j+1)]
+filter[8]*p[(i+1) + WIDTH*(j+1)];
if(result<BLACK) result = ‐result; //数値が負になっていれば‐1をかける
if(result>WHITE) result = WHITE;   //数値が255を超えていれば255に収める
filtered[i+WIDTH*j]  = (unsigned char)result;
}
}
}
空間フィルタ
GPGPU実践基礎工学104 2015/11/25
imageproc.c
モザイク処理
2015/11/25GPGPU実践基礎工学105
 画像を小さな領域に分け,その領域を全て同じ色にする
 領域内の全画素を,領域内の画素の平均値に置き換える
原画像 処理画像
void mosaic(unsigned char *f,unsigned char *filtered, int mosaicSize){
int i,j, isub,jsub;
int average;
for(j=0;j<HEIGHT;j+=mosaicSize){
for(i=0;i<WIDTH;i+=mosaicSize){
//領域内の画素の平均値を計算
average = 0;
for(jsub = 0; jsub<mosaicSize; jsub++){
for(isub = 0; isub<mosaicSize; isub++){
average += f[(i+isub) + WIDTH*(j+jsub)];
}
}
average /= (mosaicSize*mosaicSize);
//領域内の画素を計算した平均値で塗りつぶす
for(jsub = 0; jsub<mosaicSize; jsub++){
for(isub = 0; isub<mosaicSize; isub++){
filtered[(i+isub) + WIDTH*(j+jsub)] = (unsigned char)average;
}
}
}
}
}
モザイク
GPGPU実践基礎工学106 2015/11/25
imageproc.c
GPUへの移植の方針
GPGPU実践基礎工学
 画像の作成はCPUで行い,GPUへ転送
 1スレッドが1画素の処理を実行
 2重のforループを排除し,配列添字とスレッド番号を対応
 空間フィルタ
 端の画素の処理ができないので今回は処理しない
 モザイク
 領域の大きさ(横×縦)は1ブロックと同じとする
 領域内の画素の平均値の計算は非常に難易度が高い
 threadIdx.x=0,threadIdx.y=0のスレッドが平均を計算してメモ
リに書き出す
107 2015/11/25
メイン関数(GPU版)
GPGPU実践基礎工学108
#include<stdio.h>
#include<stdlib.h>
#define WHITE (255)
#define BLACK (0)
#define WIDTH  4096
#define HEIGHT WIDTH
#define Nbytes (WIDTH*HEIGHT*sizeof(unsigned char))
#define THREADX 16
#define THREADY 16
#define BLOCKX (WIDTH/THREADX)
#define BLOCKY (HEIGHT/THREADY)
void create(unsigned char *);
void print(unsigned char *);
int main(void){
unsigned char *p= (unsigned char *)malloc(Nbytes);
unsigned char *dev_p, *dev_filtered;
cudaMalloc( (void **)&dev_p, Nbytes);
cudaMalloc( (void **)&dev_filtered, Nbytes);
2015/11/25
imageproc.cu
メイン関数(GPU版)
GPGPU実践基礎工学109
//ここで空間フィルタのカーネルを宣言
float *filter;
cudaMalloc( (void **)&filter, sizeof(float)*9);
cudaMemcpy(filter, フィルタのカーネル, sizeof(float)*9, cudaMemcpyHostToDevice);
create(p); //CPUで画像を生成してGPUへ送った後,変数dev_filteredにコピーしておく
cudaMemcpy(dev_p, p, Nbytes, cudaMemcpyHostToDevice);
cudaMemcpy(dev_filtered, dev_p, Nbytes, cudaMemcpyDeviceToDevice);
dim3 block( BLOCKX,  BLOCKY, 1), thread(THREADX, THREADY, 1);
//ここで処理を行い,結果をdev_filteredに格納
//dev_filteredの内容をCPUへ送る
unsigned char *filtered = (unsigned char *)malloc(Nbytes);
cudaMemcpy(filtered, dev_filtered, Nbytes, cudaMemcpyDeviceToHost);
free(p);
free(filtered);
cudaFree(dev_p);
cudaFree(dev_filtered);
cudaFree(filter);
return 0;
}
2015/11/25
imageproc.cu
メイン関数(GPU版)
GPGPU実践基礎工学110
void create(unsigned char *p){
int i,j, x_origin,y_origin;
for(j=0;j<HEIGHT;j++){
for(i=0;i<WIDTH;i++){
p[i+WIDTH*j] = WHITE;
}
}
x_origin = 9*WIDTH/16;
y_origin = 9*HEIGHT/16;
for(i=0;i<6*WIDTH/16;i++){
for(j=i;j<6*HEIGHT/16;j++){
p[i+x_origin + WIDTH*(j+y_origin)] = BLACK;
}
}
}
void print(unsigned char *p){
int i,j;
for(j=0;j<HEIGHT;j++){
for(i=0;i<WIDTH;i++){
printf("%d %d %d¥n", i, j, p[i+WIDTH*j]);
}
printf("¥n");
}
}
2015/11/25
imageproc.cu
__global__ void negative(unsigned char *p, unsigned char *filtered){
int i,j;
i = blockIdx.x*blockDim.x + threadIdx.x; //スレッド数と配列添字の対応
j = blockIdx.y*blockDim.y + threadIdx.y; //
filtered[i+WIDTH*j] = WHITE ‐ p[i + WIDTH*j];
}
ネガティブ処理
GPGPU実践基礎工学111 2015/11/25
imageproc.cu
__global__ void hreflect(unsigned char *p, unsigned char *reflected){
int i,j;
int iref;
i = blockIdx.x*blockDim.x + threadIdx.x;
j = blockIdx.y*blockDim.y + threadIdx.y;
iref = (WIDTH‐1)‐i;  //反転後のx座標値
reflected[iref+WIDTH*j] = p[i + WIDTH*j];
}
水平反転
GPGPU実践基礎工学112 2015/11/25
imageproc.cu
__global__ void vreflect(unsigned char *p, unsigned char *reflected){
int i,j;
int jref;
i = blockIdx.x*blockDim.x + threadIdx.x;
j = blockIdx.y*blockDim.y + threadIdx.y;
jref = (HEIGHT‐1)‐j; //反転後のy座標値
reflected[i+WIDTH*jref] = p[i + WIDTH*j];
}
垂直反転
GPGPU実践基礎工学113 2015/11/25
imageproc.cu
__global__ void boxfilter(unsigned char *p, unsigned char *filtered, float *filter){
int i,j;
int result = BLACK;
i = blockIdx.x*blockDim.x + threadIdx.x;
j = blockIdx.y*blockDim.y + threadIdx.y;
if(0<i && i<WIDTH‐1 && 0<j && j<HEIGHT‐1){ //端の画素は処理をしないため,ifで処理を分岐
result =  filter[0]*p[(i‐1) + WIDTH*(j‐1)]
+filter[1]*p[(i ) + WIDTH*(j‐1)]
+filter[2]*p[(i+1) + WIDTH*(j‐1)]
+filter[3]*p[(i‐1) + WIDTH*(j  )]
+filter[4]*p[(i ) + WIDTH*(j  )]
+filter[5]*p[(i+1) + WIDTH*(j  )]
+filter[6]*p[(i‐1) + WIDTH*(j+1)]
+filter[7]*p[(i ) + WIDTH*(j+1)]
+filter[8]*p[(i+1) + WIDTH*(j+1)];
}
if(result<BLACK) result = ‐result; //数値が負になっていれば‐1をかける
if(result>WHITE) result = WHITE;   //数値が255を超えていれば255に収める
filtered[i+WIDTH*j]  = (unsigned char)result;
}
空間フィルタ
GPGPU実践基礎工学114 2015/11/25
imageproc.cu
__global__ void mosaic(unsigned char *p, unsigned char *filtered, int mosaicSize){
int i,j, isub,jsub;
int average;
i = blockIdx.x*blockDim.x + threadIdx.x;
j = blockIdx.y*blockDim.y + threadIdx.y;
if(threadIdx.x == 0 && threadIdx.y == 0){//ブロック内の1スレッドのみが処理
//領域内の画素の平均値を計算
average = 0;
for(jsub = 0; jsub<mosaicSize; jsub++){
for(isub = 0; isub<mosaicSize; isub++){
average += p[(i+isub) + WIDTH*(j+jsub)];
}
}
average /= (mosaicSize*mosaicSize);
//領域内の画素を計算した平均値で塗りつぶす
for(jsub = 0; jsub<mosaicSize; jsub++){
for(isub = 0; isub<mosaicSize; isub++){
filtered[(i+isub) + WIDTH*(j+jsub)] = (unsigned char)average;
}
}
}
}
モザイク処理
GPGPU実践基礎工学115 2015/11/25
imageproc.cu
処理時間の比較
GPGPU実践基礎工学116
 画像サイズ 4096×4096
 1ブロックあたりのスレッド数 16×16
 モザイクのサイズはスレッド数と同じ(16×16)
処理
処理時間[ms]
CPU GPU
ネガティブ処理 175 1.17
水平反転 187 1.18
垂直反転 185 1.18
空間フィルタ 553 4.13
モザイク処理 260 38.5
補足
ビットマップ画像のフォーマット
ビットマップ画像
2015/11/25GPGPU実践基礎工学119
 画像を画素(pixel)の集合として捉え,各画素の色を3
原色(赤緑青,RGB)で表す
 1画素あたり1バイト~4バイト
 jpg画像のように画像圧縮を施さないのでデータ量が画
像サイズに比例して増大
 圧縮形式もあるがあまり利用されない
 zip形式等のファイル圧縮を使うと効果的に圧縮可能
ビットマップファイルフォーマット
2015/11/25GPGPU実践基礎工学120
 ファイルの情報を表すヘッダ+画像の各画素情報
 ヘッダ
 ファイルヘッダ+情報ヘッダの合計54バイト
 ファイルヘッダ
 ファイルの種類,ファイルサイズ等
 情報ヘッダ
 画像の幅,高さ,1画素あたりのデータサイズなど
 画像の各画素の情報
ビットマップファイルフォーマット
2015/11/25GPGPU実践基礎工学121
 24bitビットマップファイルのバイナリダンプ
ファイルヘッダ
情報ヘッダ
画像情報
1画素の情報
ビットマップファイルフォーマット
2015/11/25GPGPU実践基礎工学122
 ファイルヘッダ
 エンディアン(endian, 多バイトデータの記述・格納形式)
内容 サイズ 備考
ファイルの種類 u2 ビットマップの場合はBM
ファイルサイズ(byte)
u4
16進数表記(リトルエンディアン,下位
ビットが先に書かれる)
予約領域1 u2 必ず0
予約領域2 u2 必ず0
ファイル先頭から画像までの
オフセット u4
windowsビットマップでは54
(16進数表記で36)
36 00 03 00
リトルエンディアン 00 03 00 3616=196,662 byte
ビッグエンディアン 36 00 03 0016=905,970,432 byte
ビットマップファイルフォーマット
2015/11/25GPGPU実践基礎工学123
 情報ヘッダ
内容 byte数 備考
情報ヘッダのサイズ u4 必ず40(byte, 16進数表記で28)
画像の幅(pixel) 4 16進数表記
画像の高さ(pixel) 4 16進数表記
プレーン数 u2 必ず1
色ビット数(bit/pixel) u2 1,4,8,24,32(16進数表記)
圧縮形式 u4 0,1,2,3のいずれか
画像データサイズ u4 16進数表記
水平解像度(dot/m) 4 0の場合もある
垂直解像度(dot/m) 4 0の場合もある
パレット数(使用色数) u4 0の場合もある
重要な色の数 u4 0の場合もある
ビットマップファイルフォーマット
2015/11/25GPGPU実践基礎工学124
 画像情報(24bitビットマップ)
 3原色の情報をそれぞれ1バイト(unsigned char)で保持
 3原色の並び順はBGR
 幅は行単位で4バイトの倍数に揃えられる
 画素の並びは左下から右方向,下から上方向
B G R

More Related Content

What's hot

2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層智啓 出川
 
CUDAプログラミング入門
CUDAプログラミング入門CUDAプログラミング入門
CUDAプログラミング入門NVIDIA Japan
 
C++による数値解析の並列化手法
C++による数値解析の並列化手法C++による数値解析の並列化手法
C++による数値解析の並列化手法dc1394
 
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜京大 マイコンクラブ
 
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust) GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust) 智啓 出川
 
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例智啓 出川
 
1076: CUDAデバッグ・プロファイリング入門
1076: CUDAデバッグ・プロファイリング入門1076: CUDAデバッグ・プロファイリング入門
1076: CUDAデバッグ・プロファイリング入門NVIDIA Japan
 
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS) GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS) 智啓 出川
 
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層智啓 出川
 
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)智啓 出川
 
GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)智啓 出川
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門Norishige Fukushima
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編Fixstars Corporation
 
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造智啓 出川
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) 智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調智啓 出川
 
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術智啓 出川
 
Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Fixstars Corporation
 
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介Preferred Networks
 
LUT-Network その後の話(2022/05/07)
LUT-Network その後の話(2022/05/07)LUT-Network その後の話(2022/05/07)
LUT-Network その後の話(2022/05/07)ryuz88
 

What's hot (20)

2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
2015年度GPGPU実践基礎工学 第13回 GPUのメモリ階層
 
CUDAプログラミング入門
CUDAプログラミング入門CUDAプログラミング入門
CUDAプログラミング入門
 
C++による数値解析の並列化手法
C++による数値解析の並列化手法C++による数値解析の並列化手法
C++による数値解析の並列化手法
 
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜
 
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust) GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
 
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
2015年度GPGPU実践プログラミング 第1回 GPGPUの歴史と応用例
 
1076: CUDAデバッグ・プロファイリング入門
1076: CUDAデバッグ・プロファイリング入門1076: CUDAデバッグ・プロファイリング入門
1076: CUDAデバッグ・プロファイリング入門
 
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS) GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
 
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
 
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
2015年度GPGPU実践プログラミング 第10回 行列計算(行列-行列積の高度な最適化)
 
GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
 
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
2015年度GPGPU実践基礎工学 第10回 GPUのプログラム構造
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
 
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
2015年度先端GPGPUシミュレーション工学特論 第15回 CPUとGPUの協調
 
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
2015年度GPGPU実践基礎工学 第6回 ソフトウェアによるCPUの高速化技術
 
Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門
 
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
 
LUT-Network その後の話(2022/05/07)
LUT-Network その後の話(2022/05/07)LUT-Network その後の話(2022/05/07)
LUT-Network その後の話(2022/05/07)
 

Viewers also liked

2015年度先端GPGPUシミュレーション工学特論 第6回 プログラムの性能評価指針 (Flop/Byte,計算律速,メモリ律速)
2015年度先端GPGPUシミュレーション工学特論 第6回 プログラムの性能評価指針(Flop/Byte,計算律速,メモリ律速)2015年度先端GPGPUシミュレーション工学特論 第6回 プログラムの性能評価指針(Flop/Byte,計算律速,メモリ律速)
2015年度先端GPGPUシミュレーション工学特論 第6回 プログラムの性能評価指針 (Flop/Byte,計算律速,メモリ律速)智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第3回 GPUプログラム構造の詳細 (threadとwarp)
2015年度先端GPGPUシミュレーション工学特論 第3回 GPUプログラム構造の詳細(threadとwarp)2015年度先端GPGPUシミュレーション工学特論 第3回 GPUプログラム構造の詳細(threadとwarp)
2015年度先端GPGPUシミュレーション工学特論 第3回 GPUプログラム構造の詳細 (threadとwarp)智啓 出川
 
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ智啓 出川
 
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア智啓 出川
 
2015年度GPGPU実践基礎工学 第11回 GPUでの並列 プログラミング(ベクトル和)
2015年度GPGPU実践基礎工学 第11回 GPUでの並列プログラミング(ベクトル和)2015年度GPGPU実践基礎工学 第11回 GPUでの並列プログラミング(ベクトル和)
2015年度GPGPU実践基礎工学 第11回 GPUでの並列 プログラミング(ベクトル和)智啓 出川
 
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算 (移流方程式)
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算(移流方程式)2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算(移流方程式)
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算 (移流方程式)智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第8回 偏微分方程式の差分計算 (拡散方程式)
2015年度先端GPGPUシミュレーション工学特論 第8回 偏微分方程式の差分計算(拡散方程式)2015年度先端GPGPUシミュレーション工学特論 第8回 偏微分方程式の差分計算(拡散方程式)
2015年度先端GPGPUシミュレーション工学特論 第8回 偏微分方程式の差分計算 (拡散方程式)智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第7回 総和計算(Atomic演算)
2015年度先端GPGPUシミュレーション工学特論 第7回 総和計算(Atomic演算)2015年度先端GPGPUシミュレーション工学特論 第7回 総和計算(Atomic演算)
2015年度先端GPGPUシミュレーション工学特論 第7回 総和計算(Atomic演算)智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第1回補足 GPGPU教育計算機システムGROUSEの利用方法
2015年度先端GPGPUシミュレーション工学特論 第1回補足 GPGPU教育計算機システムGROUSEの利用方法2015年度先端GPGPUシミュレーション工学特論 第1回補足 GPGPU教育計算機システムGROUSEの利用方法
2015年度先端GPGPUシミュレーション工学特論 第1回補足 GPGPU教育計算機システムGROUSEの利用方法智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第1回 先端シミュレーションおよび産業界におけるGPUの役割
2015年度先端GPGPUシミュレーション工学特論 第1回 先端シミュレーションおよび産業界におけるGPUの役割2015年度先端GPGPUシミュレーション工学特論 第1回 先端シミュレーションおよび産業界におけるGPUの役割
2015年度先端GPGPUシミュレーション工学特論 第1回 先端シミュレーションおよび産業界におけるGPUの役割智啓 出川
 
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第2回 GPUによる並列計算の概念と メモリアクセス
2015年度先端GPGPUシミュレーション工学特論 第2回 GPUによる並列計算の概念とメモリアクセス2015年度先端GPGPUシミュレーション工学特論 第2回 GPUによる並列計算の概念とメモリアクセス
2015年度先端GPGPUシミュレーション工学特論 第2回 GPUによる並列計算の概念と メモリアクセス智啓 出川
 
2015年度GPGPU実践プログラミング 第11回 画像処理
2015年度GPGPU実践プログラミング 第11回 画像処理2015年度GPGPU実践プログラミング 第11回 画像処理
2015年度GPGPU実践プログラミング 第11回 画像処理智啓 出川
 
2015年度GPGPU実践プログラミング 第13回 多粒子の運動
2015年度GPGPU実践プログラミング 第13回 多粒子の運動2015年度GPGPU実践プログラミング 第13回 多粒子の運動
2015年度GPGPU実践プログラミング 第13回 多粒子の運動智啓 出川
 
2015年度GPGPU実践プログラミング 第14回 N体問題
2015年度GPGPU実践プログラミング 第14回 N体問題2015年度GPGPU実践プログラミング 第14回 N体問題
2015年度GPGPU実践プログラミング 第14回 N体問題智啓 出川
 
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第5回 GPUのメモリ階層の詳細 (様々なメモリの利用)
2015年度先端GPGPUシミュレーション工学特論 第5回 GPUのメモリ階層の詳細(様々なメモリの利用)2015年度先端GPGPUシミュレーション工学特論 第5回 GPUのメモリ階層の詳細(様々なメモリの利用)
2015年度先端GPGPUシミュレーション工学特論 第5回 GPUのメモリ階層の詳細 (様々なメモリの利用) 智啓 出川
 
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)智啓 出川
 
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造智啓 出川
 

Viewers also liked (20)

2015年度先端GPGPUシミュレーション工学特論 第6回 プログラムの性能評価指針 (Flop/Byte,計算律速,メモリ律速)
2015年度先端GPGPUシミュレーション工学特論 第6回 プログラムの性能評価指針(Flop/Byte,計算律速,メモリ律速)2015年度先端GPGPUシミュレーション工学特論 第6回 プログラムの性能評価指針(Flop/Byte,計算律速,メモリ律速)
2015年度先端GPGPUシミュレーション工学特論 第6回 プログラムの性能評価指針 (Flop/Byte,計算律速,メモリ律速)
 
2015年度先端GPGPUシミュレーション工学特論 第3回 GPUプログラム構造の詳細 (threadとwarp)
2015年度先端GPGPUシミュレーション工学特論 第3回 GPUプログラム構造の詳細(threadとwarp)2015年度先端GPGPUシミュレーション工学特論 第3回 GPUプログラム構造の詳細(threadとwarp)
2015年度先端GPGPUシミュレーション工学特論 第3回 GPUプログラム構造の詳細 (threadとwarp)
 
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第4回 CPUのアーキテクチャ
 
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
2015年度GPGPU実践基礎工学 第7回 シングルコアとマルチコア
 
2015年度GPGPU実践基礎工学 第11回 GPUでの並列 プログラミング(ベクトル和)
2015年度GPGPU実践基礎工学 第11回 GPUでの並列プログラミング(ベクトル和)2015年度GPGPU実践基礎工学 第11回 GPUでの並列プログラミング(ベクトル和)
2015年度GPGPU実践基礎工学 第11回 GPUでの並列 プログラミング(ベクトル和)
 
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
2015年度GPGPU実践基礎工学 第9回 GPUのアーキテクチャ
 
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算 (移流方程式)
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算(移流方程式)2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算(移流方程式)
2015年度先端GPGPUシミュレーション工学特論 第9回 偏微分方程式の差分計算 (移流方程式)
 
2015年度先端GPGPUシミュレーション工学特論 第8回 偏微分方程式の差分計算 (拡散方程式)
2015年度先端GPGPUシミュレーション工学特論 第8回 偏微分方程式の差分計算(拡散方程式)2015年度先端GPGPUシミュレーション工学特論 第8回 偏微分方程式の差分計算(拡散方程式)
2015年度先端GPGPUシミュレーション工学特論 第8回 偏微分方程式の差分計算 (拡散方程式)
 
2015年度先端GPGPUシミュレーション工学特論 第7回 総和計算(Atomic演算)
2015年度先端GPGPUシミュレーション工学特論 第7回 総和計算(Atomic演算)2015年度先端GPGPUシミュレーション工学特論 第7回 総和計算(Atomic演算)
2015年度先端GPGPUシミュレーション工学特論 第7回 総和計算(Atomic演算)
 
2015年度先端GPGPUシミュレーション工学特論 第1回補足 GPGPU教育計算機システムGROUSEの利用方法
2015年度先端GPGPUシミュレーション工学特論 第1回補足 GPGPU教育計算機システムGROUSEの利用方法2015年度先端GPGPUシミュレーション工学特論 第1回補足 GPGPU教育計算機システムGROUSEの利用方法
2015年度先端GPGPUシミュレーション工学特論 第1回補足 GPGPU教育計算機システムGROUSEの利用方法
 
2015年度先端GPGPUシミュレーション工学特論 第1回 先端シミュレーションおよび産業界におけるGPUの役割
2015年度先端GPGPUシミュレーション工学特論 第1回 先端シミュレーションおよび産業界におけるGPUの役割2015年度先端GPGPUシミュレーション工学特論 第1回 先端シミュレーションおよび産業界におけるGPUの役割
2015年度先端GPGPUシミュレーション工学特論 第1回 先端シミュレーションおよび産業界におけるGPUの役割
 
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
2015年度GPGPU実践基礎工学 第9回補足 GROUSEの利用方法
 
2015年度先端GPGPUシミュレーション工学特論 第2回 GPUによる並列計算の概念と メモリアクセス
2015年度先端GPGPUシミュレーション工学特論 第2回 GPUによる並列計算の概念とメモリアクセス2015年度先端GPGPUシミュレーション工学特論 第2回 GPUによる並列計算の概念とメモリアクセス
2015年度先端GPGPUシミュレーション工学特論 第2回 GPUによる並列計算の概念と メモリアクセス
 
2015年度GPGPU実践プログラミング 第11回 画像処理
2015年度GPGPU実践プログラミング 第11回 画像処理2015年度GPGPU実践プログラミング 第11回 画像処理
2015年度GPGPU実践プログラミング 第11回 画像処理
 
2015年度GPGPU実践プログラミング 第13回 多粒子の運動
2015年度GPGPU実践プログラミング 第13回 多粒子の運動2015年度GPGPU実践プログラミング 第13回 多粒子の運動
2015年度GPGPU実践プログラミング 第13回 多粒子の運動
 
2015年度GPGPU実践プログラミング 第14回 N体問題
2015年度GPGPU実践プログラミング 第14回 N体問題2015年度GPGPU実践プログラミング 第14回 N体問題
2015年度GPGPU実践プログラミング 第14回 N体問題
 
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
2015年度GPGPU実践基礎工学 第1回 学際的分野における先端シミュレーション技術の歴史
 
2015年度先端GPGPUシミュレーション工学特論 第5回 GPUのメモリ階層の詳細 (様々なメモリの利用)
2015年度先端GPGPUシミュレーション工学特論 第5回 GPUのメモリ階層の詳細(様々なメモリの利用)2015年度先端GPGPUシミュレーション工学特論 第5回 GPUのメモリ階層の詳細(様々なメモリの利用)
2015年度先端GPGPUシミュレーション工学特論 第5回 GPUのメモリ階層の詳細 (様々なメモリの利用)
 
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
2015年度GPGPU実践プログラミング 第8回 総和計算(高度な最適化)
 
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
2015年度GPGPU実践プログラミング 第2回 GPUのアーキテクチャとプログラム構造
 

Similar to 2015年度GPGPU実践基礎工学 第12回 GPUによる画像処理

2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用智啓 出川
 
GPGPU Education at Nagaoka University of Technology: A Trial Run
GPGPU Education at Nagaoka University of Technology: A Trial RunGPGPU Education at Nagaoka University of Technology: A Trial Run
GPGPU Education at Nagaoka University of Technology: A Trial Run智啓 出川
 
2012 1203-researchers-cafe
2012 1203-researchers-cafe2012 1203-researchers-cafe
2012 1203-researchers-cafeToshiya Komoda
 
GPGPUを用いた大規模高速グラフ処理に向けて
GPGPUを用いた大規模高速グラフ処理に向けてGPGPUを用いた大規模高速グラフ処理に向けて
GPGPUを用いた大規模高速グラフ処理に向けてKoichi Shirahata
 
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介Drecom Co., Ltd.
 
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)智啓 出川
 
気候モデル放射カーネルのGPUへの移植と高速化
気候モデル放射カーネルのGPUへの移植と高速化気候モデル放射カーネルのGPUへの移植と高速化
気候モデル放射カーネルのGPUへの移植と高速化Takateru Yamagishi
 
Neural Global Shutter: Learn to Restore Video from a Rolling Shutter Camera w...
Neural Global Shutter: Learn to Restore Video from a Rolling Shutter Camera w...Neural Global Shutter: Learn to Restore Video from a Rolling Shutter Camera w...
Neural Global Shutter: Learn to Restore Video from a Rolling Shutter Camera w...tomoaki0705
 
(JP) GPGPUがPostgreSQLを加速する
(JP) GPGPUがPostgreSQLを加速する(JP) GPGPUがPostgreSQLを加速する
(JP) GPGPUがPostgreSQLを加速するKohei KaiGai
 
ディープラーニング最新動向と技術情報
ディープラーニング最新動向と技術情報ディープラーニング最新動向と技術情報
ディープラーニング最新動向と技術情報NVIDIA Japan
 
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境智啓 出川
 
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール智啓 出川
 
プログラム説明 kgPhotonMapping v0-1-0
プログラム説明 kgPhotonMapping v0-1-0プログラム説明 kgPhotonMapping v0-1-0
プログラム説明 kgPhotonMapping v0-1-0Takahiro KOGUCHI
 
なぜGPUはディープラーニングに向いているか
なぜGPUはディープラーニングに向いているかなぜGPUはディープラーニングに向いているか
なぜGPUはディープラーニングに向いているかNVIDIA Japan
 
Hello, DirectCompute
Hello, DirectComputeHello, DirectCompute
Hello, DirectComputedasyprocta
 
PCCC21:東京大学情報基盤センター 「『計算・データ・学習』融合によるスーパーコンピューティングの革新、そして東大センターのこれから」
PCCC21:東京大学情報基盤センター 「『計算・データ・学習』融合によるスーパーコンピューティングの革新、そして東大センターのこれから」PCCC21:東京大学情報基盤センター 「『計算・データ・学習』融合によるスーパーコンピューティングの革新、そして東大センターのこれから」
PCCC21:東京大学情報基盤センター 「『計算・データ・学習』融合によるスーパーコンピューティングの革新、そして東大センターのこれから」PC Cluster Consortium
 
GPGPU Seminar (GPGPU and CUDA Fortran)
GPGPU Seminar (GPGPU and CUDA Fortran)GPGPU Seminar (GPGPU and CUDA Fortran)
GPGPU Seminar (GPGPU and CUDA Fortran)智啓 出川
 

Similar to 2015年度GPGPU実践基礎工学 第12回 GPUによる画像処理 (20)

2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
2015年度先端GPGPUシミュレーション工学特論 第14回 複数GPUの利用
 
GPGPU Education at Nagaoka University of Technology: A Trial Run
GPGPU Education at Nagaoka University of Technology: A Trial RunGPGPU Education at Nagaoka University of Technology: A Trial Run
GPGPU Education at Nagaoka University of Technology: A Trial Run
 
2012 1203-researchers-cafe
2012 1203-researchers-cafe2012 1203-researchers-cafe
2012 1203-researchers-cafe
 
GPGPUを用いた大規模高速グラフ処理に向けて
GPGPUを用いた大規模高速グラフ処理に向けてGPGPUを用いた大規模高速グラフ処理に向けて
GPGPUを用いた大規模高速グラフ処理に向けて
 
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介
 
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
2015年度GPGPU実践基礎工学 第3回 GPUクラスタ上でのプログラミング(CUDA)
 
RAPIDS 概要
RAPIDS 概要RAPIDS 概要
RAPIDS 概要
 
気候モデル放射カーネルのGPUへの移植と高速化
気候モデル放射カーネルのGPUへの移植と高速化気候モデル放射カーネルのGPUへの移植と高速化
気候モデル放射カーネルのGPUへの移植と高速化
 
Neural Global Shutter: Learn to Restore Video from a Rolling Shutter Camera w...
Neural Global Shutter: Learn to Restore Video from a Rolling Shutter Camera w...Neural Global Shutter: Learn to Restore Video from a Rolling Shutter Camera w...
Neural Global Shutter: Learn to Restore Video from a Rolling Shutter Camera w...
 
(JP) GPGPUがPostgreSQLを加速する
(JP) GPGPUがPostgreSQLを加速する(JP) GPGPUがPostgreSQLを加速する
(JP) GPGPUがPostgreSQLを加速する
 
ディープラーニング最新動向と技術情報
ディープラーニング最新動向と技術情報ディープラーニング最新動向と技術情報
ディープラーニング最新動向と技術情報
 
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
2015年度GPGPU実践基礎工学 第14回 GPGPU組込開発環境
 
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
2015年度GPGPU実践プログラミング 第6回 パフォーマンス解析ツール
 
プログラム説明 kgPhotonMapping v0-1-0
プログラム説明 kgPhotonMapping v0-1-0プログラム説明 kgPhotonMapping v0-1-0
プログラム説明 kgPhotonMapping v0-1-0
 
なぜGPUはディープラーニングに向いているか
なぜGPUはディープラーニングに向いているかなぜGPUはディープラーニングに向いているか
なぜGPUはディープラーニングに向いているか
 
Hello, DirectCompute
Hello, DirectComputeHello, DirectCompute
Hello, DirectCompute
 
CG2013 14
CG2013 14CG2013 14
CG2013 14
 
PCCC21:東京大学情報基盤センター 「『計算・データ・学習』融合によるスーパーコンピューティングの革新、そして東大センターのこれから」
PCCC21:東京大学情報基盤センター 「『計算・データ・学習』融合によるスーパーコンピューティングの革新、そして東大センターのこれから」PCCC21:東京大学情報基盤センター 「『計算・データ・学習』融合によるスーパーコンピューティングの革新、そして東大センターのこれから」
PCCC21:東京大学情報基盤センター 「『計算・データ・学習』融合によるスーパーコンピューティングの革新、そして東大センターのこれから」
 
20130126 sc12-reading
20130126 sc12-reading20130126 sc12-reading
20130126 sc12-reading
 
GPGPU Seminar (GPGPU and CUDA Fortran)
GPGPU Seminar (GPGPU and CUDA Fortran)GPGPU Seminar (GPGPU and CUDA Fortran)
GPGPU Seminar (GPGPU and CUDA Fortran)
 

More from 智啓 出川

Fortranが拓く世界、VSCodeが架ける橋
Fortranが拓く世界、VSCodeが架ける橋Fortranが拓く世界、VSCodeが架ける橋
Fortranが拓く世界、VSCodeが架ける橋智啓 出川
 
Very helpful python code to find coefficients of the finite difference method
Very helpful python code to find coefficients of the finite difference methodVery helpful python code to find coefficients of the finite difference method
Very helpful python code to find coefficients of the finite difference method智啓 出川
 
Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?智啓 出川
 
Pythonによる累乗近似
Pythonによる累乗近似Pythonによる累乗近似
Pythonによる累乗近似智啓 出川
 
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)智啓 出川
 
オブジェクト指向Fortranが拓く(はずだった)新しい世界
オブジェクト指向Fortranが拓く(はずだった)新しい世界オブジェクト指向Fortranが拓く(はずだった)新しい世界
オブジェクト指向Fortranが拓く(はずだった)新しい世界智啓 出川
 
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...智啓 出川
 
Cuda fortranの利便性を高めるfortran言語の機能
Cuda fortranの利便性を高めるfortran言語の機能Cuda fortranの利便性を高めるfortran言語の機能
Cuda fortranの利便性を高めるfortran言語の機能智啓 出川
 
PGI CUDA FortranとGPU最適化ライブラリの一連携法
PGI CUDA FortranとGPU最適化ライブラリの一連携法PGI CUDA FortranとGPU最適化ライブラリの一連携法
PGI CUDA FortranとGPU最適化ライブラリの一連携法智啓 出川
 
教育機関でのJetsonの活用の可能性
教育機関でのJetsonの活用の可能性教育機関でのJetsonの活用の可能性
教育機関でのJetsonの活用の可能性智啓 出川
 
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用 (高度な最適化)
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用(高度な最適化)2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用(高度な最適化)
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用 (高度な最適化)智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用 (支配方程式,CPUプログラム)
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用(支配方程式,CPUプログラム)2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用(支配方程式,CPUプログラム)
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用 (支配方程式,CPUプログラム)智啓 出川
 
2015年度先端GPGPUシミュレーション工学特論 第10回 Poisson方程式の求解 (線形連立一次方程式)
2015年度先端GPGPUシミュレーション工学特論 第10回 Poisson方程式の求解(線形連立一次方程式)2015年度先端GPGPUシミュレーション工学特論 第10回 Poisson方程式の求解(線形連立一次方程式)
2015年度先端GPGPUシミュレーション工学特論 第10回 Poisson方程式の求解 (線形連立一次方程式)智啓 出川
 

More from 智啓 出川 (14)

Fortranが拓く世界、VSCodeが架ける橋
Fortranが拓く世界、VSCodeが架ける橋Fortranが拓く世界、VSCodeが架ける橋
Fortranが拓く世界、VSCodeが架ける橋
 
Very helpful python code to find coefficients of the finite difference method
Very helpful python code to find coefficients of the finite difference methodVery helpful python code to find coefficients of the finite difference method
Very helpful python code to find coefficients of the finite difference method
 
Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?
 
Pythonによる累乗近似
Pythonによる累乗近似Pythonによる累乗近似
Pythonによる累乗近似
 
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
数値計算結果のPythonによる後処理について(1次元データのピーク値およびその位置の推定)
 
オブジェクト指向Fortranが拓く(はずだった)新しい世界
オブジェクト指向Fortranが拓く(はずだった)新しい世界オブジェクト指向Fortranが拓く(はずだった)新しい世界
オブジェクト指向Fortranが拓く(はずだった)新しい世界
 
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
Schematic diagrams of GPUs' architecture and Time evolution of theoretical FL...
 
Cuda fortranの利便性を高めるfortran言語の機能
Cuda fortranの利便性を高めるfortran言語の機能Cuda fortranの利便性を高めるfortran言語の機能
Cuda fortranの利便性を高めるfortran言語の機能
 
PGI CUDA FortranとGPU最適化ライブラリの一連携法
PGI CUDA FortranとGPU最適化ライブラリの一連携法PGI CUDA FortranとGPU最適化ライブラリの一連携法
PGI CUDA FortranとGPU最適化ライブラリの一連携法
 
教育機関でのJetsonの活用の可能性
教育機関でのJetsonの活用の可能性教育機関でのJetsonの活用の可能性
教育機関でのJetsonの活用の可能性
 
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
GPGPU Seminar (Accelerataion of Lattice Boltzmann Method using CUDA Fortran)
 
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用 (高度な最適化)
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用(高度な最適化)2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用(高度な最適化)
2015年度先端GPGPUシミュレーション工学特論 第13回 数値流体力学への応用 (高度な最適化)
 
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用 (支配方程式,CPUプログラム)
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用(支配方程式,CPUプログラム)2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用(支配方程式,CPUプログラム)
2015年度先端GPGPUシミュレーション工学特論 第11回 数値流体力学への応用 (支配方程式,CPUプログラム)
 
2015年度先端GPGPUシミュレーション工学特論 第10回 Poisson方程式の求解 (線形連立一次方程式)
2015年度先端GPGPUシミュレーション工学特論 第10回 Poisson方程式の求解(線形連立一次方程式)2015年度先端GPGPUシミュレーション工学特論 第10回 Poisson方程式の求解(線形連立一次方程式)
2015年度先端GPGPUシミュレーション工学特論 第10回 Poisson方程式の求解 (線形連立一次方程式)
 

2015年度GPGPU実践基礎工学 第12回 GPUによる画像処理