Ubuntu 11.10 64bit でIntel OpenCL SDKを動かした。
しかし、アホなことにGPUは動かしていない。
私が愛用している Thinkpad X220 (iCore-5 2520M, Intel HD Graphics 3000)でヘラヘラ試していたが、
よく調べると、HD Graphics 3000にはOpenCLサポートは無かった。(へらへら~)
Ubuntuで Intel OpenCLを動かすための日本語の情報は少ないので一応、ここに記す。
Ubuntu で、Intel OpenCLを動かすには、下のページに書いてあるとおり。
http://mhr3.blogspot.com/2011/05/opencl-on-ubuntu.html
それをなぞってやったこと。
1. Intel OpenCLサイトから、SDKをダウンロード(rpmパッケージ)
下記がメインの入り口であろうか?
http://software.intel.com/en-us/articles/vcsource-tools-opencl-sdk/
具体的なダウンロードは下記。
http://software.intel.com/en-us/articles/download-intel-opencl-sdk/
今回は、"Intel® OpenCL SDK Downloads (updated September 26th)" と書いてあった。
"intel_ocl_sdk_1.5_x64.tgz" - package for 64-bit operating systems.
をダウンロード。
(なぜか、私の場合、ファイルが途中で切れていて、何週間もえらく悩んだ。ファイルを再度ゲットしたら嘘のようにうまく行った)
このファイルを、適当なディレクトリで、
% tar xvzf intel_ocl_sdk_1.5_x64.tgz
として、展開する。
すると、rpmとライセンス書きが出てくる。(苦笑)
28469424 2011-09-14 23:28 intel_ocl_sdk_1.5_x64.rpm
23751 2011-09-14 23:28 license.txt
以降、面倒なので、わたしは、次のようにして、rootになって作業する。
% sudo tcsh
自分のパスワードを入力して、あとはroot権限で作業。プロンプトは'#'
2. Ubuntuは、rpmではダメなので、debに変換する。
rpmからdebに変換するには、 rpmとalien のパッケージが必要。入っていなければ、下記のようにインストール。
# apt-get install rpm alien
3. rpm -> deb 変換
# alien --to-deb intel_ocl_sdk_1.5_x64.rpm
変換が終わると、
28472592 2012-01-06 19:45 intel-ocl-sdk_1.5-15294_amd64.deb
というファイルができた。(Intelなのに、amd64とか付いてて可愛い)
alienの実行には、root権限が無ければならない(fakerootコマンドと併用する方法もあり)。
4. OpenCL SDKのインストール
# dpkg -i intel-ocl-sdk_1.5-15294_amd64.deb
5. そして、libnumaを入れていなければ、次のようにしてインストール。
# apt-get install libnuma1
ここで、
/usr/lib64/ に、
drwxr-xr-x 3 root root 4096 2012-01-06 19:48 OpenCL/
-rwxr-xr-x 1 root root 33683 2011-09-14 23:27 libOpenCL.so*
とかできている。
6. /etc/OpenCL/vendors/intelocl64.icdを確認。
当該ファイルが無ければ、
# echo "libintelocl.so" > /etc/OpenCL/vendors/intelocl64.icd
とする。
7.OpenCL ヘッダーファイル
OpenCL ヘッダーファイルは、 /usr/include/CLにある。
メインのライブラリは、/usr/lib64/libOpenCL.so 。
好みによって、
# ldconfig /usr/lib64
# ldconfig /usr/lib64/OpenCL/vendors/intel
とかやるといいかも。(自分はやってしまった)
ldconfig をやらなくとも、
各ユーザの ~/.profile や、 ~/.cshrc で、
環境変数 LD_LIBRARY_PATHに/usr/lib64/OpenCL/vendors/intelを加えておけばよい。
bsh系
export LD_LIBRARY_PATH=/usr/lib64/OpenCL/vendors/intel:$LD_LIBRARY_PATH
csh系
setenv LD_LIBRARY_PATH /usr/lib64/OpenCL/vendors/intel:$LD_LIBRARY_PATH
ちなみに、/usr/lib64/OpenCL/vendors/intel/ にllcとか入っている。
以上で、Intel OpenCL SDKは、インストールできた。
OpenCLを試す その1
ここで述べた簡単なプログラムの俺バージョンの tgz ファイルをダウンロードできます。(platとvadd)
「Intel® OpenCL SDK User's Guide」 (http://software.intel.com/file/38642)
の 4.4 Working with the OpenCL Installable Client Driver (ICD) に
書いてある例題で、OpenCL SDKが入っているかを確認。
#include <opencl.h>
#include <cl_platform.h>
cl_platform_id * platforms = NULL;
char vendor_name[128] = {0};
cl_uint num_platforms = 0;
cl_uint num_devices=0;
int aaa()
{
// get number of available platforms
cl_int err = clGetPlatformIDs(0, NULL, & num_platforms);
printf("err=%d,num_platforms=%d\n", err, num_platforms );
if(CL_SUCCESS != err) {
printf("err!\n");
}
platforms = (cl_platform_id*)malloc(sizeof(cl_platform_id)* num_platforms);
if(NULL == platforms){
printf("malloc err!\n");
}
err = clGetPlatformIDs(num_platforms, platforms, NULL);
printf("clGetPlatformIDs err=%d platforms[0]=%x\n", err, platforms[0] );
if(CL_SUCCESS != err){
printf("clGetPlatformIDs err!\n");
}
for (cl_uint ui=0; ui< num_platforms; ++ui){
printf("platforms[ui]=%x\n", platforms[ui] );
err = clGetPlatformInfo(platforms[ui], CL_PLATFORM_VENDOR,
128*sizeof(char), vendor_name, NULL);
printf("err=%d,vendor_name=%s\n", err, vendor_name );
if(CL_SUCCESS != err){ printf("error !\n"); }
err = clGetPlatformInfo(platforms[ui], CL_PLATFORM_NAME,
128*sizeof(char), vendor_name, NULL);
printf("err=%d,NAME=%s\n",err, vendor_name );
if(CL_SUCCESS != err){ printf("error !\n"); }
err = clGetPlatformInfo(platforms[ui], CL_PLATFORM_VERSION,
128*sizeof(char), vendor_name, NULL);
printf("err=%d,VERSION=%s\n",err, vendor_name );
if(CL_SUCCESS != err){ printf("error !\n"); }
err = clGetPlatformInfo(platforms[ui], CL_PLATFORM_PROFILE,
128*sizeof(char), vendor_name, NULL);
printf("err=%d,profile=%s\n",err, vendor_name );
if(CL_SUCCESS != err){ printf("error !\n"); }
err = clGetPlatformInfo(platforms[ui], CL_PLATFORM_EXTENSIONS,
128*sizeof(char), vendor_name, NULL);
printf("err=%d,extensions=%s\n",err, vendor_name );
if(CL_SUCCESS != err){ printf("error !\n"); }
if(vendor_name != NULL){
if(!strcmp(vendor_name, "Intel Corporation")){
return platforms[ui];
}
}
}
// handle error
}
#define XXX CL_DEVICE_TYPE_ALL
//#define XXX CL_DEVICE_TYPE_DEFAULT
//#define XXX CL_DEVICE_TYPE_ACCELERATOR
//#define XXX CL_DEVICE_TYPE_GPU
//#define XXX CL_DEVICE_TYPE_CPU
cl_device_id device_id = NULL;
dev()
{
int ret;
ret = clGetDeviceIDs( platforms[0], XXX,0,NULL, &num_devices);
printf("clGetDeviceIDs err=%d,num_devices=%d\n", ret, num_devices );
ret = clGetDeviceIDs( platforms[0], XXX,1,&device_id, &num_devices);
printf("clGetDeviceIDs err=%d,num_devices=%d, device_id=%x\n", ret, num_devices, device_id );
}
int main(int argc, char *argv[])
{
aaa();
dev();
}
上記で、Intelの例は、
#define XXX CL_DEVICE_TYPE_ALL
としている。
私のThinkpad X220は、GPUでのOpenCLがサポートされていないので、
#define XXX CL_DEVICE_TYPE_ALL
または、
#define XXX CL_DEVICE_TYPE_CPU
でしか動作しない。
ret = clGetDeviceIDs( platforms[0], CL_DEVICE_TYPE_GPU, 1,&device_id, &num_devices);
で、エラーが返る。そりゃそうだ、GPUを使えないのだもの。
また、他社のOpenGLでは、
CL_DEVICE_TYPE_DEFAULT
が許されているようだが、今回のIntel OpenCL SDKで、私の環境では、エラーが返る。(コンパイルは正常に通る)
ひょっとして、DefaultがGPUになっていて、今回は、それが使用できないから、エラーなのか???
platの実行結果
% ./plat
err=0,num_platforms=1
clGetPlatformIDs err=0 platforms[0]=9b4080
platforms[ui]=9b4080
err=0,vendor_name=Intel(R) Corporation
err=0,NAME=Intel(R) OpenCL
err=0,VERSION=OpenCL 1.1 LINUX
err=0,profile=FULL_PROFILE
err=-30,extensions=FULL_PROFILE
error !
clGetDeviceIDs err=0,num_devices=1
clGetDeviceIDs err=0,num_devices=1, device_id=9c18e0
OpenCLを試す その2
やっぱ、OpenCL kernelを動かさないといけないよね。
ということで、Webをふらふらと彷徨ったら、ばっちり初心者向けを書いてくれている人が! (優しい)
Getting started with OpenCL and GPU Computing
http://www.thebigblob.com/getting-started-with-opencl-and-gpu-computing/
ここに、単なるベクトル(一次元行列)の足し算の例題がある。
ソースもダウンロードできる。
俺バージョンの tgz ファイルをダウンロードできます。(platとvadd)
ここのmain (俺バージョンでは vadd.c)の 43行あたりの
ret = clGetDeviceIDs( platform_id, CL_DEVICE_TYPE_DEFAULT, 1,
&device_id, &ret_num_devices);
の CL_DEVICE_TYPE_DEFAULT は、私のGPU無し環境では、当然 CL_DEVICE_TYPE_CPU にしなければならない(とほほ)
俺バージョンの場合は、
% make とやれば、
vaddという実行形式ファイルができる。
openCLカーネル・プログラムは、
vector_add_kernel.cl
という名称で、同じディレクトリ(カレント・ディレクトリ)に置く。
この名称は、vadd.c の中にハード・コードされている。
% ./vadd
clGetPlatformIDs err=0,num_platforms=1, platform_id=b1fba0
clGetDeviceIDs err=0,num_platforms=1, device_id=b2b930
0 + 1024 = 1024
1 + 1023 = 1024
2 + 1022 = 1024
:
:
1022 + 2 = 1024
1023 + 1 = 1024
という結果が出て、めでたしめでたし。
Intel OpenCLとしては、正常動作しているようだ。
Intel HD Graphics 2500だと、OpenCLが動くようだ。上位っぽい名称の3000でOpenCLが動かないとは…今回は、とてもトホホ感のあるチャレンジだった。
次は、NotePCで挑戦するのはやめて、素直に据え置き機で試そう…