コードカキマス反撃のシゲハル

新しく学んだことをまとめます

CUDAによるGPUプログラミング

春に下書きして、投稿してませんでした。

GPUとはGraphics Processing Unit の略称で、PCやワークステーションで画像処理を担当する部品の一つです。ゲーミングPCとかだったらグラフィックボードを大体積んでますね。画面の描写の役割とかを果たしてくれます。GPUを利用することで、大量のデータを複数のプロセッサで同時かつ並列処理することができます。

今大学で勉強中のCUDAを利用した、GPUプログラミングの基本をまとめておこうかと思います。

 

基本の流れは以下です。

f:id:aspr_aspr:20170708030556p:plain

ここで、カーネルとはGPU側に担当してもらう処理関数みたいなものです。

 

具体的にどういう風に記述するのか、GPUの構造を確認しながらまとめます。

f:id:aspr_aspr:20170708031114p:plain

出典:「CUDAプログラミングの基本 パートⅠ」 by NVIDIA

GPUで関数を実行する時に特に意識するのがこの、グリッド、ブロック、スレッドです。スレッドはカーネル関数が動作させた時のプログラムの最小単位を表します。これが同時に何個も動作することで高速な処理が可能です。

ブロックは複数のスレッドの集合体で、グリッドは複数のブロックの集合体と考えれば簡単化と思います。

ブロック、スレッドは1次元や2次元などで定義することができます。

 

ここで、画像の簡単な処理を実行したいと思います。使う画像は「lenna」という画像処理分野ではよく使われる綺麗なお姉さんの画像を使って画像の二値化(白黒に)します。

ソースは以下。

 

#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>


#define N 256


__global__ void shirokuro(unsigned char *original_image_gpu, unsigned char *monokuro_image_gpu) {
 int i,j;
// 以下の2行はブロック、スレッドの通し番号を表す。
 i= blockIdx.x * blockDim.x + threadIdx.x;
 j= blockIdx.y * blockDim.y + threadIdx.y;
//以下の行で、全てのスレッドで同時実行できる。
 if(original_image[i*N+j] < 128){
  monokuro_image_gpu[i*N+j] = 0
 }
 else{
  monokuro_image_gpu[i*N+J] = 255
 }
}


int main(void){
 unsigned char *original_image, *monokuro_image;
 unsigned char *original_image_gpu, *monokuro_image_gpu;
 float time_ms = 0.0f;//時間計測の変数
 cudaEvent_t start, stop;//時間計測の為のイベント
 FILE *fp;


// host側で元画像と処理後画像のメモリ領域を確保
 original_image = (unsigned char*)malloc(sizeof(unsigned char)*N*N);
 monokuro_image = (unsigned char*)malloc(sizeof(unsigned char)*N*N);


//元画像、「lennna.256」を配列に格納
 fp = fopen("lennna.256", "rb");
 fread(f, sizeof(unsigned char), N*N, fp);
 fclose(fp);


//cudaにおける時間計測イベント作成
 cudaEventCreate(&start);
 cudaEventCreate(&stop);


// cuda側(GPU)でメモリ確保
 cudaMalloc((void**)&original_image_gpu, sizeof(unsigned char)*N*N);
 cudaMalloc((void**)&monokuro_image_gpu, sizeof(unsigned char)*N*N);


// cuda側に元画像をコピー
 cudaMemcpy(original_image_gpu, original_image, sizeof(unsigned char)*N*N, cudaMemcpyHostToDevice);


// block, threads の確保
 dim3 blocks(16,16,1);
 dim3 threads(16,16,1);


// cuda時間計測イベントで計測開始
 cudaEventRecord(start, 0);


//カーネル関数の実行
 shirokuro<<< blocks, threads >>> (original_image_gpu, monokuro_image_gpu);


//実行が終わり、monokuro_image_gpu に処理後の画像が入っているので、それをmonokuro_imageに渡す
 cudaMemcpy(monokuro_image, monokuro_image_gpu, sizeof(unsigned char)*N*N, cudaMemcpyDeviceToHost);


//GPUメモリ解放
 cudaFree(monokuro_image_gpu);
 cudaFree(original_image_gpu);


// cpu側でメモリ解放
 free(original_image);
 free(monokuro_image);


// ホスト側の配列から画像生成
 fp = fopen("lenna_new.256", "wb");
 fwrite(monokuro_image, sizeof(unsigned char), N*N, fp);
 fclose(fp);


//cuda時間計測終了
 cudaEventRecord(stop, 0);
 cudaEventSynchronize(stop);


//かかった時間を出力
 cudaEventElapsedTime(&time_ms, start, stop);
 printf("time: %f ms\n",time_ms);


//不要になったcudaの時間計測イベントを消去
 cudaEventDestroy(start);
 cudaEventDestroy(stop);
}

 

jQueryの学習

jQueryを学習してみました。railsではjQueryが標準的に装備されているので、基本のところから学び直すことにしました。ちなみにjQueryとはJavaScriptコードをより簡単にに記述できるようにするために設計されたJavaScriptライブラリ、です!

 

追記 2017/06/29

 

公式サイトはコチラ

jquery.com

 

何ができるのか?

HTMLの要素やその要素に指定したクラスやidを指定して、cssを指定したり、動きをつけたり出来ます。その他にもページの移動とかも出来ます。まだまだ学習中。。。

基本的な書き方

$('指定したい要素やclass').method(引数); 

これでOKです。この書き方を基本に関数を書いたり、メソッドを複数つなぎ合わせたりしながら、(チェーンメソッドという)機能を作っていきます。

 

具体的にどんなものがあるのか

hideメソッド:要素を見えなくする。

fadeIn,fadeOutメソッド:要素をフェードイン、フェードアウトさせる。

cssメソッド:cssスタイルを指定できる。

clickメソッド:指定された要素をクリックしたときに、どんな動作をさせるか記述出来る。

hoverメソッド:要素の上にカーソル置いたとき、離したときにどんな動作をするか記述できる。

## 6/29追記

リンクを指定してロケーションさせたり、モーダル画面を出現させるような実装をしました。クリック時にcssクラスを付与したり外したりなので2行でかけました。簡単ですね。javascriptも合わせて勉強すれば自由度高めでいろんなもの作れそうです。

 

実際のWebサイトを想像すると、clickやhoverの中で様々なメソッドを実行するのが多そうな感じがしますねー。他の言語とかで出来るのかもしれませんが??

最近使った実装が、ボタンをクリックすると、新規登録用のモーダルが出現するような処理ですね。非常に簡単だけれど、インパクトがありそうな実装だと思いますね。

 

テスト開発(ruby on rails)

テスト開発とは

開発においては定義した関数・メソッドが正しく動作するか、期待していない結果を返さないか、またはアクセスが正しいか、などのテストを書くことがあります。

 

テストの例

サイトにおいて、ログインしなければ閲覧することの出来ないページがあるとします。非ログイン状態でそのページのURLを入力した場合にアクセス出来てはサイトとして良くないでしょう。

そこで、テスト開発では、ログイン時に正しくアクセス出来ること、非ログイン時にはアクセス出来ず元のページへ戻る(そう実装していれば)というようなコードを書きます。

 

テストを書く理由

開発においては機能追加や元々のデータ仕様の変更が起こります。長い開発においては、過去に書いたコードをいちいち覚えるのも大変ですし、他人が書いたコードを編集します。その時に、予期せぬエラーが発生する可能性十分にあります。

テストを書いていれば、そのエラーを検知し、未然にトラブルを防ぐことが可能です。堅牢なシステムを構築するためにはテストは不可欠なものです。

 

どのようにテストを書くか

パターンは色々ありますが、大まかには以下のような流れです。

①テストに使うテストデータの作成

②テストしたい関数、アクセスの実行

③予期した結果が返って来るかチェック、例外処理をキャッチできているかチェック

 大体はこのような感じです。

 

細かい記法は省略。ちなみに、railsのテストしか書いた事がないです。テストを書くときに参考にしている方のQiitaはコチラ。

使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 - Qiita

使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」 - Qiita

などなど・・・

Webエンジニアのインターン始めました。

2017年の2月末からwebエンジニアのインターンを始めました。

きっかけは色々で、採用時に出来ることと言えば、基本的なHTMLとCSSの仕組みの理解と簡単なrubyruby on railsの記法の理解だけでした。

入って新しい記法や環境を知ったので、備忘録的に載せていきます。

 

view編(html)

  • html.erb
  • haml.html

html.erbは簡単に言うと、htmlコードの中にruby,railsのコードを埋め込み出来る記法です。htmlコード中に<%>タグでくくるとブラウザが読み込んで展開してくれます。railsを初めて勉強する場合はこの記法からになるかと。

hamlはインデントやタグの書き方、railsのコードの記法をものすごく簡略化できるといったイメージです。書き方はQiitaの記事を参考にして学びました。詳しくは以下のリンクで。

qiita.com

view編(css)

  • sass
  • scss

どちらもcssを書きやすくしたものです。 スタイルを変数として定義出来たり、クラス名が途中まで同じものに対して同じようなコードを書かなくてよかったり。僕の職場ではscssのほうがメイン。参考にしたQiitaの記事を載せておきます。

qiita.com

railsについては学習しているサイト、サービスを紹介します。とはいえ、ネット上で学習できるレベルは限られているので、ある程度書けるようになったら、自分でアプリケーションを作るか、インターンするほうが力は付きます。

 

 

http://dotinstall.com/prog-8.com

後は分からないことをひたすらググるか、railsの本を辞書引きしたら簡単なことはわかります。