Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
PyOpenCLによる
 GPGPU入門
お前、誰よ

尾上 洋介(@_likr)

関西大学大学院 総合情報学研究科 M2

 ナップザック問題とかやってる

PythonとかOCamlも好き
おのうえとGPGPU
2010年夏 卒研のためGPGPUに取り組む

2010年冬 GPGPUで論文投稿

2011年夏 某社でGPGPU関係のインターンに参加

2011年冬 kyoto.pyでPyOpenCLの布教活動

2012年春 修論のためのGPUプログラムを開発中?
GPGPUとは
GPGPU : General Purpose Computing on GPU
  GPUによる汎目的計算

2003年頃から利用が開始

スパコンなどでも利用

今後モバイルにも普及が進む(?)
GPU処理の特徴

数百∼数千のコア

高速なメモリアクセス

高い費用対効果

演算性能向上率が高い
OpenCLとは
ヘテロジニアス並列環境のためのフレームワーク

マルチコアCPU、GPU、DSP、FPGA

    Host            Device
    CPU            Processor
            Bus
   Memory          Memory
Why OpenCL ?

各社のGPUが対応

 NVIDIA、AMD、Intel (Ivy Bridge)

非プラットフォーム依存(建前上は)

ピュアなC/C++
Why Python ?
ソースコードが簡潔

コンパイル不要

カーネルコードは通常のOpenCLと共通

Pythonの各種ライブラリを利用可能

GPGPU概念の習得、アプリケーション開発に最適
Agenda
1.   概要

2.   GPGPUの基礎

3.   PyOpenCLによるGPGPU入門

4.   PyOpenCLのArray

5.   PythonによるOpenCLアプリケーション開発
GPGPUの基礎
ヘテロジニアス環境
異なる種類のプロセッサを組み合わせた
ハイブリッドシステム

独立したメモリ領域

    Host            GPU
    CPU              SM
            PCIe
   Memory          Memory
GPUのアーキテクチャ

Streaming Multiprocessor(SM)
                                     GPU
  GPUの処理実行単位
                                         SM
Streaming Processor(SP)                       Shared Memory

  CUDAコア                            SP          Registers



GPU全体のリソースと                      Global Memory
SM毎のリソース
                               NVIDIA GPUの構成(簡易)
GPUのメモリ階層

       SP毎             SM毎            全体

高速     Register     Shared Memory Constant Memory


低速   Local Memory                  Global Memory
ワークグループとワークアイテム

ワークアイテムが処理の
最小単位(≒スレッド)

ワークグループは
ワークアイテムの集まり

ワークグループごとに
SMで処理される

ワークアイテム、
ワークグループは      OpenCL Specification 1.1より

3次元のIDを持つ
高速なGPU処理のために
データ並列          スレッド間の同期を減
               らす
メモリ転送を減らす
               条件分岐を減らす
グローバルメモリアク
セスを減らす         …

アクセスが高速なメモ
リを使う         処理特性の理解が重要
GPGPUの適用分野
行列・ベクトルの演算

画像処理、音声処理

流体計算、天文計算

線形計画問題、ナップザック問題、
スケジューリング問題、金融工学
PyOpenCLによるGPGPU入門
プラットフォームとデバイス

各社から提供される         NVIDIA OpenCL
OpenCLプラットフォームは
                      GPU 1
1台のマシンに同居可能
                      GPU 2
各プラットフォームには
1個以上のデバイス          Intel OpenCL
実行時にプラットフォームと          CPU
デバイスを選択               GPU
インストール
1.   OpenCL環境のインストール

      NVIDIA、AMD、Intel、Apple…

2.   依存ライブラリのインストール

      $ easy_install numpy

      $ easy_install mako

3.   PyOpenCLのインストール

      $ easy_install pyopencl
OpenCLプログラムの登場人物

Context
                                 Context
CommandQueue                      Host
   デバイスの制御               Command Queue
Buffer GPU上のメモリ
                                  GPU
Kernel GPUで実行されるプログラム               Program
                        Buffer
Program Kernelの集まり                       Kernel
基本手順
1.   Context、CommandQueue、
     Programの作成
                              Host            GPU
2.   GPUのメモリ確保
                              CPU              SM
3.   GPUへのデータ転送                       PCIe
                             Memory          Memory
4.   GPUでの計算

5.   GPUからのデータ転送
Contextの作成
                                   1   #!/usr/bin/env python
                                   2   # -*- coding: utf-8 -*-
                                   3
create_some_context()              4
                                   5
                                       import pyopencl as cl
                                       import numpy
実行時にデバイスと                          6
                                   7   # Contextの作成
プラットフォームを                          8 ctx = cl.create_some_context()
                                   9
選択                                10 # CommandQueueの作成
                                  11 queue = cl.CommandQueue(ctx)


        [onoue@localhost test]$ python sample.py
        Choose device(s):
        [0] <pyopencl.Device 'Tesla C2050' on 'NVIDIA CUDA' at 0xfd4000>
        [1] <pyopencl.Device 'GeForce GT 240' on 'NVIDIA CUDA' at 0xc85df0>
        Choice, comma-separated [0]:0
Programの作成
                13 # Programの作成
カーネル関数は         14   prg = cl.Program(ctx, """//CL//
                15   __kernel void sum(
OpenCL C言語で実装   16       __global const float *a,
                17       __global const float *b,
                18       __global float *c
Pythonソース内に     19
                20
                     )
                     {
                21       int gid = get_global_id(0);
カーネル関数を         22       c[gid] = a[gid] + b[gid];
                23   }
文字列で埋め込む        24   """).build()
デバイス側メモリの確保

ホストとデバイス 26 # ホスト側メモリ確保
それぞれでメモリ
                   27   a = numpy.random.rand(50000).astype(numpy.float32)
                   28   b = numpy.random.rand(50000).astype(numpy.float32)
                   29   a_plus_b = numpy.empty_like(a)
                   30
領域を確保              31   # デバイス側メモリ確保
                   32   mf = cl.mem_flags
                   33   size = a.nbytes
                   34   a_buf = cl.Buffer(ctx, mf.READ_ONLY, size)
ホスト側には             35
                   36
                        b_buf = cl.Buffer(ctx, mf.READ_ONLY, size)
                        dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, size)


numpy.ndarrayを使用
メモリ転送とカーネル呼び出し
ホストのメモリはデバイスから直接操作不可

デバイスのメモリはホストから直接操作不可

カーネル関数呼び出し時に
ワークアイテム、ワークグループのサイズを指定
 38 # デバイスへのメモリ転送
 39 cl.enqueue_copy(queue, a_buf, a)
 40 cl.enqueue_copy(queue, b_buf, b)
 41
 42 # カーネル呼び出し
 43 prg.sum(queue, a.shape, None, a_buf, b_buf, dest_buf)
 44
 45 # デバイスからのメモリ転送
 46 cl.enqueue_copy(queue, a_plus_b, dest_buf)
PyOpenCLのArray
pyopencl.array
numpyライクなインタフェース

ベクトル、行列演算

乱数列生成

リダクション、スキャンのショートカット

デバイスを意識せずに演算の高速化が可能
サンプルコード
11 # numpyのarrayをpyopenclのarrayに変換
12 a_host = numpy.random.rand(5000).astype(numpy.float32)
13 a = pyopencl.array.to_device(queue, a_host)
14
15 # ゼロクリアされたarrayの生成
16 b = pyopencl.array.zeros(queue, (5000,), numpy.float32)
17
18 # 値がランダムなarrayの生成
19 c = clrandom.rand(queue, (5000,), numpy.float32)
20
21 # 演算
22   a += 2
23   a /= 3
24   a += c
25   print a.get()
26
27   # 数学関数
28 print clmath.sin(c).get()
29
30 # リダクション
31 print pyopencl.array.sum(b)
リダクション
      10 1 8 -1 0 -2 3 5
総和
      10 -1 11 4
最小値

最大値   21 3


…     24
Reductionの高速化
共有メモリの使用

warpダイバージェントを減らす

多段リダクション

…
考慮する要因がたくさん!
カスタムリダクション

      チューニングされたカーネルを必要な部分
      の実装のみで利用可能


 9   sum_square_expr = '+'.join('x{0}[i] * x{0}[i]'.format(i) for i in range(n))
10   arguments = ', '.join('__global float* x{0}'.format(i) for i in range(n))
11   kernel = ReductionKernel(
12           context,
13           numpy.int32,
14           neutral='0',
15           reduce_expr='a + b',
16           map_expr='({0} <= 1.f) ? 1 : 0'.format(sum_square_expr),
17           arguments=arguments)
Pythonによる
OpenCLアプリケーション開発
PyOpenCLアプリケーション




PythonのWebフレームワーク、GUIツールキット、そ
の他ライブラリなどとシームレスに統合可能
デモ1 OpenGL連携


PyOpenGL / PyOpenCL による流体シミュレーション
デモ2 PyQt4


Gaussian FIlter
ソースコード

デモ1

 https://bitbucket.org/likr/pyopencl_rungekutta
デモ2

 https://bitbucket.org/likr/gaussian
最後に
まとめ
OpenCLで非プラットフォーム依存な
GPUコンピューティングを習得

PyOpenCLによる簡潔なコーディングで
OpenCLの概念を素早く吸収

Pythonの各種ライブラリを使った
アプリケーション開発
参考資料
CUDA プログラミング入門(白山工業 森野編)
http://www.youtube.com/user/NVIDIAJapan

はじめてのCUDAプログラミング
ー脅威の開発環境[GPU+CUDA]を使いこなす!
http://www.amazon.co.jp/dp/4777514773

PyCUDAの紹介 - PythonとAWSですぐ始めるGPUコンピューティング
http://www.slideshare.net/likr/pycuda
参考資料
改訂新版 OpenCL入門 1.2対応
マルチコアCPU・GPUのための並列プログラミング
http://www.amazon.co.jp/dp/4844331728

The OpenCL Specification Version 1.2
http://www.khronos.org/registry/cl/specs/opencl-1.2.pdf

PyOpenCL
http://mathema.tician.de/software/pyopencl

PyOpenCLハンズオン in kyoto.py 資料
http://pykyoto201109-pyopencl.s3-website-ap-northeast-1.amazonaws.com/pyopencl.html
ご清聴ありがとうございました

More Related Content

PyOpenCLによるGPGPU入門

Editor's Notes