クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

カーネルの書き方 ベクトルの足し算

このレッスンのあとで: 自分の番号を求め、範囲を確かめて計算するカーネルを書いて、起動を真似られる。

60分のレッスンコマンド2件並列計算ラボ:GPU を使わずに GPU の考え方を JupyterLab で

カーネルとは、1つのスレッドがする仕事を書いた関数

カーネルとは、GPUの1つのスレッドがする仕事を書いた関数です。起動すると、全部のスレッドが同じカーネルを、それぞれ自分の要素に走らせます。

このレッスンでは、2つの配列を足すカーネルを、Pythonで書いて動かします。ラボにGPUはなく、起動はPythonのループで真似ます。

このレッスンのゴール

メモ

自分の番号を求め、範囲を確かめて計算するカーネルを書いて、起動を真似られる。

重要な言葉

ことばいみれい
カーネル1つのスレッドがする仕事を書いた関数
起動全スレッドにカーネルを走らせること
範囲の確認自分の番号が、データの中かを確かめることif i < n
ブロックの数要素を覆うのに必要な、ブロックの個数
何もしないスレッド範囲の外にいて、仕事をしないスレッド

学生が入力するセルは、このプレビューでは空白です。

カーネルは、自分の番号を求めて仕事をする

カーネルの中身は3つの手順です。自分の通し番号 i を求めます。i がデータの中かを確かめます。中なら、i番目だけを計算します。

全スレッドが同じ手順を走らせるので、ループは要りません。ループに当たる部分を、起動が受け持ちます。

7個を、ブロックの大きさ3で処理する

ブロックスレッドの番号通し番号すること
00, 1, 20, 1, 2全員が計算する
10, 1, 23, 4, 5全員が計算する
20, 1, 26, 7, 86だけ計算し、7と8は何もしない

学生が入力するセルは、このプレビューでは空白です。

カーネルと起動をPythonで真似る

コード: python
# カーネルは、1つのスレッドがする仕事です。起動は、全スレッドにそれを走らせます。
prices = [120, 300, 80, 450, 60, 90, 200]
shipping = [50, 50, 50, 50, 50, 50, 50]
n = len(prices)
result = [0] * n
block_dim = 3
grid_dim = (n + block_dim - 1) // block_dim


def kernel(block_idx, thread_idx):
    i = block_idx * block_dim + thread_idx
    if i < n:
        result[i] = prices[i] + shipping[i]
        return 1
    return 0


worked = 0
for block_idx in range(grid_dim):
    for thread_idx in range(block_dim):
        worked = worked + kernel(block_idx, thread_idx)
print("ブロック数:", grid_dim, "仕事をしたスレッド:", worked)
print(result)
# prices に値段を2つ足して、ブロック数がどう変わるか見ましょう。

範囲の確認を忘れると、データの外を触る

要素の数がブロックの大きさの倍数でないと、スレッドが余ります。余ったスレッドの番号は、データの長さ以上です。

確認なしに計算すると、存在しない場所を読み書きします。だからカーネルの最初に、番号がデータの中かを確かめます。

よくある間違い

注意

スレッドの数は、要素の数にぴったり合わせられると思いがちです。ブロックの大きさが決まっていると、余りが出ます。ブロックの数は切り上げ、余ったスレッドには範囲の確認で何もさせません。

ラボの端末で、カーネルのコードを読む

ラボにGPUはありません。ラボのスクリプトも、同じカーネルをPythonで真似ています。下の Run は、そのコードを表示するだけです。

コードの中の def kernel が、カーネルです。ブロックの番号とスレッドの番号を受け取り、block_idx * block_dim + thread_idx で自分の番号を求めます。

スクリプトのコードを読む

コマンド
docker exec jupyter cat steps/kernel.py

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

カーネルの行を探す

コマンド
docker exec jupyter grep -n "def kernel" steps/kernel.py

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

さらに挑戦: 多すぎるスレッド

1000個の要素に、ブロックの大きさ256で起動すると、ブロックは4つ、スレッドは1024個です。

何もしないスレッドは、24個です。要素が1025個になると、ブロックの数はどうなるでしょうか。自分の言葉で説明しましょう。

このラボとソースについて: 並列計算ラボ:GPU を使わずに GPU の考え方を JupyterLab で

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。