ARMのOpenCL(GPGPU)対応メモ

## はじめに
先日のARMのカンファレンスに行った友達が
「MaliがGPGPU推しだった」
とか言っていたのでいろいろ調べてたら面白くなってサイズが大きくなったのでいったんまとめてみます。
追記:
[GPGPU Advent Calendar]( http://atnd.org/events/34539 "GPGPU Advent Calendar" )の20日目にしてみました。
## 結論

+ GeForceはそもそもGPGPUのサポートが無いっぽい(かのNVIDIAなのに…)
+ Mali、PowerVRはGPGPUをサポートしているものの、本家SDKとしては出ていない(gccであればLinaroがサポートを入れてるかも…かも…(詳しく追う気がしなかった))
+ AdrenoはGPGPUをサポートし本家SDKを出している。

**Adreno素晴らしいです。おわり。**

## 雑多な知識
さて、と言うわけでMaliついでにPowerVRとAdrenoとGeForce(Tegra)についても調べたのでざっとリンクを交えつつ雑多な知識を書いていきます。
### 基本的な用語の説明
#### ARMとSoC
以下で出てくるデバイスはすべて1つのSoCとして構成されています。つまりARM CPUコアと各社のGPUが1つの半導体に載っていて、同じメモリ空間を共有しています。
x86と違いPCI-Expressだのは出てこないので、GPUだけ変更みたいなことはもちろん出来ません。
#### GPGPUとOpenCL
ARM業界的には、GPGPU=OpenCLと考えてよいようです。ARMのCPUコアもVFPとかNEONみたいなSIMD演算機構があるから、そっちだけに対応してOpenCL対応って言うのも可能な気もしますが(よく知らない)、とりあえずそういうことをやっている会社はないみたいです。
以後、OpenCL=GPGPU。
#### OpenCL
OpenCLとは言ってもEmbedded Profileとかいろいろあるみたいなんですが、調べていないので詳しい人教えてください。

###今回調べたGPUデバイス
では今回調べたそれぞれのデバイスについてのざっくりとした解説。
####Mali
開発はARM (イギリス)
http://www.arm.com/ja/products/multimedia/mali-graphics-plus-gpu-compute/index.php

採用例はSAMSUNG製CPUのExynosとか、中華タブレットでよく見かけるAllWinner A10とか。最新機種だとNexus10とかChromebookとかですね(どちらもExynos搭載)
ARMのCPUを使ってるデバイスって結構多い割に、Maliを採用してるデバイスはそんな思い浮かばないのはわりと歴史が浅いから?
http://en.wikipedia.org/wiki/Mali_(GPU)

OpenCLのサポートはMali-600系から。
この辺に解説が。
http://blogs.arm.com/multimedia/775-opencl-with-arm-mali-gpu-computingwith-no-compromises/
本家からはSDK出てないと思う。
http://www.malideveloper.com/developer-resources/sdks.php
けど、これはたぶんオープンになってないだけで、ARMのことだからNDA結んだ会社には出てるんじゃ無いかなぁとか想像。

商品として出ているのはExynos5だけなんだけど、すでにNexus10とChromebookが買えるのでLinaroツールチェインで試したい人はやってみてね、と。

####PowerVR
開発はImagination Technologies (イギリス)
http://www.imgtec.com/jp/powervr/powervr-graphics.asp

採用例はとても幅が広くて、iPhoneのCPUやIntelのAtom、SEGAのNAOMIプラットホーム最近だとPS Vitaとかも。
開発時にはNECも入っていたような気もするけど、最近は知らない。昔はPC向けのビデオカードでも出てました。

OpenCLのサポートはSGX535でEmbeddedProfileに対応して、その後の5XTシリーズ(SGX543とか)からはフル対応したのかな?
なんか適切な解説を見つけられなかった…。
本家SDKは出てないような。
http://www.imgtec.com/powervr/insider/sdkdownloads/
これもくれと言えば…

端末的にはiPhoneの3GS以降で使えるってことになるんだけど、iOSのSDKはOpenCLをサポートしていないのでなんとも言えず。MacOSのSDKはサポートしてるのにね。Apple、OpenCL推しだったんだから頑張れ…

Atomにも入ってるのでIntelのOpenCL SDKの説明を眺めてみたんだけど、
http://software.intel.com/en-us/vcsource/tools/opencl-sdk
Coreに載ってるHDGraphicsには対応してると書かれているのに対して、AtomのGMAには対応してるって書いてない気がする。

####Adreno
開発はQUALCOMM (アメリカ)
https://developer.qualcomm.com/discover/chipsets-and-modems/adreno-gpu

同社製CPUであるSnapdragonに搭載されていて、ざっくり言うとiPhoneとGalaxyじゃないスマートフォンはほとんどこれ。

下を見るとホントにQUALCOMMの天下だなぁ…
![]( http://gigaom2.files.wordpress.com/2011/12/chipchart_bigger.jpg )
http://gigaom.com/2011/12/21/will-2012-be-any-different-for-intels-mobile-plans/
より

元々はATIが開発していたモバイル系のビデオコントローラImageonがベースで、AMDがATIを買収した後にImageonの部門をQUALCOMMが買い取ったもの。
その流れを引き継いでかウィキペディアでもImageonのページにAdrenoのラインナップが書いてますね。
http://en.wikipedia.org/wiki/Imageon

OpenCLのサポートはAdreno320から。
解説はこの辺が参考になる。
http://www.itmedia.co.jp/mobile/articles/1208/02/news089_2.html
日本で売ってる端末だとOptipusG、HTC J butterflyなど。Nexus端末ならNexus4。

本家SDKが
https://developer.qualcomm.com/mobile-development/mobile-technologies/gaming-graphics-optimization-adreno/tools-and-resources
にあって、OpenCLのサンプルが付属してた。後ほど簡単に紹介。

####GeForce
開発はNVIDIA(アメリカ)
同社製CPUのTegraに搭載されていて、MicrosoftのSurfaceやNexus7、あとごくたまにスマートフォンにも乗ってる。
想像だけどPC版の昔のGeForceをシュリンクして載っけてるだけに思える(公開情報はないけど)
次のTegra4からOpenCLのサポートが入るかもって話を見かけますね。
もう少し頑張りましょう。

## AdrenoSDK付属のソースを眺めてみる
AdrenoSDKに付いてくるOpenCLのサンプルを眺めてみましょうかね。
先ほど紹介したサイトからSDKをダウンロードし(要登録)インストールすると、
**C:¥AdrenoSDK¥Samples¥OpenCL¥opencl_sdk**
というディレクトリが見つかります。
Android端末で実行できるみたいですね。
ウェーブレット変換のサンプルも入ってるみたいです。
**C:¥AdrenoSDK¥Samples¥OpenCL¥opencl_sdk¥src¥hello_cl**
と辿ると、Main関数が見つかります。

```cpp:hello_main.c
extern int hello_cl(void);

int main(){
    return hello_cl();
}
```

CPUとGPUが定義されてるみたいですね。
 
```cpp:hello_cl.cpp

int hello_cl(void) {
    helloCL CLApp;
    int selected_device = CL_DEVICE_TYPE_DEFAULT;

#if defined(USE_CPU)
    selected_device = CL_DEVICE_TYPE_CPU;
#elif defined(USE_GPU)
    selected_device = CL_DEVICE_TYPE_GPU;
#endif

#if defined(USE_GPU) && defined(USE_CPU)
#error "Both USE_CPU and USE_GPU defined - unsupported"
#endif

    CLApp.initHost();
    CLApp.initCLPlatform(selected_device);
    CLApp.initCLBuffer();
    CLApp.initCLKernel();
    CLApp.runCL();
    CLApp.verify();
    CLApp.cleanupCL();
	LOGI("Hello CL finished successfully");
    return 0;
}
```


では実行して…と行きたいところですが、残念ながら筆者はSnapdragonS4Proな端末を持ってないので実行できません。

この人と同じだわー。
http://www.geeks3d.com/forums/index.php?topic=2844.0

興味を持たれた方はOptimusG辺りを買ってきて動かしてみてください。

以上、雑多な知識のお話でした。