カテゴリー別アーカイブ: OpenCL

OpenCLのマンデルブロ集合

ホストプログラム
[cpp]
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<CL/cl.h>
#include<string>

#define MAX_SOURCE_SIZE (0x100000)
#define MEM_SIZE (1000)

using namespace std;

int main()
{
//char string[MEM_SIZE];

FILE *fp;
char fileName[] = "./calc.cl";
char *source_str;
size_t source_size;

fp = fopen(fileName, "r");
if(!fp)
{
cout << "file failed" <<endl;
exit(1);
}
source_str = (char *)malloc(MAX_SOURCE_SIZE);
source_size = fread(source_str,1,MAX_SOURCE_SIZE,fp);
fclose(fp);

cl_int status;
cl_platform_id platforms[2];
cl_uint num_platforms;
status = clGetPlatformIDs(2, platforms, &num_platforms);
//cout << status << endl;

cl_device_id devices;
cl_uint num_devices;
cl_context context;
status = clGetDeviceIDs(platforms[1], CL_DEVICE_TYPE_GPU, 4, &devices, &num_devices);
//cout << status << endl;

context = clCreateContext(NULL, 4, &devices, NULL, NULL, &status);
//cout << status << endl;

cl_command_queue queue;
queue = clCreateCommandQueue(context, devices, 0, &status);
//cout <<"queue:"<<status << endl;

cl_program program;
program = clCreateProgramWithSource(context, 1, (const char**)&source_str, &source_size, &status);
//cout << status << endl;

status = clBuildProgram(program, num_devices, &devices, NULL, NULL, NULL);
//cout << status << endl;

/*////////////////////////

size_t logsize;
status = clGetProgramBuildInfo(program,devices,CL_PROGRAM_BUILD_LOG,0,NULL,&logsize);
if(status == CL_SUCCESS)
{
char *logbuffer;
logbuffer = new char[logsize + 1];
if(logbuffer == NULL)
{
cout << "memory allocation failed."<<endl;
//return;
}

status = clGetProgramBuildInfo(program,devices,CL_PROGRAM_BUILD_LOG,logsize,logbuffer,NULL);
if(status == CL_SUCCESS)
{
logbuffer[logsize]=’\0’;
cout << "build log" << endl;
cout << logbuffer << endl;
}
delete [] logbuffer;
}

*////////////////////////

cl_kernel kernel;
kernel = clCreateKernel(program, "calc", &status);
//cout << status << endl;

float Outx[MEM_SIZE];
float Outy[MEM_SIZE];
bool OutCheck[MEM_SIZE][MEM_SIZE];
Outx[0] = -2;
Outy[0] = -2;
for(int i= 0; i < MEM_SIZE-1 ;i++)
{
Outx[i+1] = Outx[i] + (4.0 / MEM_SIZE);
Outy[i+1] = Outy[i] + (4.0 / MEM_SIZE);

for(int j = 0; j < MEM_SIZE ;j++)
{
OutCheck[i][j] = 0;
}
}

cl_mem memoutx, memouty, memoutcheck;
memoutx = clCreateBuffer(context, CL_MEM_READ_WRITE, MEM_SIZE * sizeof(float), NULL, &status);
//cout <<status<<endl;
memouty = clCreateBuffer(context, CL_MEM_READ_WRITE, MEM_SIZE * sizeof(float), NULL, &status);
//cout <<status<<endl;
memoutcheck = clCreateBuffer(context, CL_MEM_READ_WRITE, MEM_SIZE * MEM_SIZE * sizeof(bool), NULL, &status);
//cout <<status<<endl;

status = clEnqueueWriteBuffer( queue, memoutx, CL_TRUE, 0, MEM_SIZE * sizeof( float ), Outx, 0, NULL, NULL );
//cout << status << endl;
status = clEnqueueWriteBuffer( queue, memouty, CL_TRUE, 0, MEM_SIZE * sizeof( float ), Outy, 0, NULL, NULL );
//cout << status << endl;
status = clEnqueueWriteBuffer( queue, memoutcheck, CL_TRUE, 0, MEM_SIZE * MEM_SIZE * sizeof( bool ), OutCheck, 0, NULL, NULL );
//cout << status << endl;

status = clSetKernelArg(kernel, 0,sizeof(cl_mem),(void *)&memoutx);
status = clSetKernelArg(kernel, 1,sizeof(cl_mem),(void *)&memouty);
status = clSetKernelArg(kernel, 2,sizeof(cl_mem),(void *)&memoutcheck);
//cout <<"カーネルに渡す引数セット:"<<status<<endl;

//status = clEnqueueTask(queue, kernel, 0, NULL, NULL);
size_t global_work_size[] = {MEM_SIZE * MEM_SIZE};
size_t local_work_size[] = {MEM_SIZE};
status = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, global_work_size, local_work_size, 0, NULL, NULL);
if( status < 0){
cout <<"実行:"<<status<<endl;
cout << CL_DEVICE_MAX_WORK_GROUP_SIZE << endl;
exit(0);
}

//status = clEnqueueReadBuffer(queue, memoutx, CL_TRUE, 0, MEM_SIZE * sizeof(float), Out, 0, NULL, NULL);
//status = clEnqueueReadBuffer(queue, memouty, CL_TRUE, 0, MEM_SIZE * sizeof(float), Out, 0, NULL, NULL);
status = clEnqueueReadBuffer(queue, memoutcheck, CL_TRUE, 0, MEM_SIZE * MEM_SIZE * sizeof(bool), OutCheck, 0, NULL, NULL);
//cout <<"結果取り出し:"<<status<<endl;

for(int i = 0;i < MEM_SIZE; i++)
{
for(int j = 0;j < MEM_SIZE; j++)
{
if(OutCheck[i][j] == 0){
cout << Outx[i]<< " " << Outy[j] << endl;
}
}
}

clReleaseMemObject(memoutx);
clReleaseMemObject(memouty);
clReleaseMemObject(memoutcheck);
clReleaseKernel(kernel);
clReleaseProgram(program);
clReleaseCommandQueue(queue);
clReleaseContext(context);
}
[/cpp]

カーネルプログラム
[cpp]
#define MEM_SIZE (1000)
__kernel void
calc(__global float *outx,
__global float *outy,
__global bool outcheck[MEM_SIZE][MEM_SIZE] )
{

#define MaxCalcNum 100

int width = 2, height = 2, j = 0;
int out[MEM_SIZE*MEM_SIZE];

#pragma OPENCL EXTENSION cl_khr_fp64:enable
//int index_x = get_global_id(0);
//int index_y = get_global_id(1);
int index_x = get_group_id(0);
int index_y = get_local_id(0);

if(index_x > MEM_SIZE)index_x = 1;
if(index_y > MEM_SIZE)index_y = 1;
double prevX = 0.0f;
double prevY = 0.0f;

for(int i = 0; i < MaxCalcNum ; i++)
{
double newX = (prevX * prevX) – (prevY * prevY) + outx[index_x];
double newY = 2.0f * prevX * prevY + outy[index_y];

if ((newX * newX) + (newY * newY) > 4.0f)
{
outcheck[index_x][index_y] = -1;
break;
}
else
{
prevX = newX;
prevY = newY;
}
}
}
[/cpp]

画像出力

$ g++ -o main_cp main_cp.cpp -lOpenCL
$ ./main_cp > mandel.txt
$ gnuplot
> set terminal png
> set out "mandel.png"
> plot "mandel.txt"

OpenCLの環境(プラットホーム、デバイス)表示

[cpp]
#include <CL/cl.h>
#include <iostream>

using namespace std;

int main(){

/*–Platform取得–*/
cl_platform_id id[3];//プラットホームID

cl_int num = 3;//プラットホームを3つまで見つける
cl_uint Rnum;//実際に取得したプラットホーム数
cl_char name[1024];//プラットホーム名

clGetPlatformIDs(num,id,&Rnum);
cout<<"Platform Max Number = "<<Rnum<<endl<<endl;

for(int i = 0;i < Rnum;i++)//プラットホームを探し、すべてのプラットホームを表示
{
clGetPlatformInfo(id[i],CL_PLATFORM_NAME,sizeof(name),name,NULL);
cout<<"Platform Name = "<<name<<endl;

/*–デバイス取得–*/
cl_device_id dev[10];//デバイスID(構造体のアドレスが格納される)

cl_uint DC;//実際に取得したデバイス数
cl_char buff[1024];//デバイス名
cl_int num1 = 10;
clGetDeviceIDs(id[i],CL_DEVICE_TYPE_ALL,num1,dev,&DC);//プラットホームID,デバイスタイプ,
cout<<"Device Max Number = "<<DC<<endl;

for(int j= 0;j < DC;j++)
{

clGetDeviceInfo(dev[j],CL_DEVICE_NAME,sizeof(buff),buff,NULL);
cout<<" Device Name = "<<buff<<endl;
}
cout << endl;
}
}
[/cpp]

OpenCLのエラーコード

めも
[cpp]
// Error Codes
#define CL_SUCCESS 0
#define CL_DEVICE_NOT_FOUND -1
#define CL_DEVICE_NOT_AVAILABLE -2
#define CL_COMPILER_NOT_AVAILABLE -3
#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4
#define CL_OUT_OF_RESOURCES -5
#define CL_OUT_OF_HOST_MEMORY -6
#define CL_PROFILING_INFO_NOT_AVAILABLE -7
#define CL_MEM_COPY_OVERLAP -8
#define CL_IMAGE_FORMAT_MISMATCH -9
#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10
#define CL_BUILD_PROGRAM_FAILURE -11
#define CL_MAP_FAILURE -12

#define CL_INVALID_VALUE -30
#define CL_INVALID_DEVICE_TYPE -31
#define CL_INVALID_PLATFORM -32
#define CL_INVALID_DEVICE -33
#define CL_INVALID_CONTEXT -34
#define CL_INVALID_QUEUE_PROPERTIES -35
#define CL_INVALID_COMMAND_QUEUE -36
#define CL_INVALID_HOST_PTR -37
#define CL_INVALID_MEM_OBJECT -38
#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39
#define CL_INVALID_IMAGE_SIZE -40
#define CL_INVALID_SAMPLER -41
#define CL_INVALID_BINARY -42
#define CL_INVALID_BUILD_OPTIONS -43
#define CL_INVALID_PROGRAM -44
#define CL_INVALID_PROGRAM_EXECUTABLE -45
#define CL_INVALID_KERNEL_NAME -46
#define CL_INVALID_KERNEL_DEFINITION -47
#define CL_INVALID_KERNEL -48
#define CL_INVALID_ARG_INDEX -49
#define CL_INVALID_ARG_VALUE -50
#define CL_INVALID_ARG_SIZE -51
#define CL_INVALID_KERNEL_ARGS -52
#define CL_INVALID_WORK_DIMENSION -53
#define CL_INVALID_WORK_GROUP_SIZE -54
#define CL_INVALID_WORK_ITEM_SIZE -55
#define CL_INVALID_GLOBAL_OFFSET -56
#define CL_INVALID_EVENT_WAIT_LIST -57
#define CL_INVALID_EVENT -58
#define CL_INVALID_OPERATION -59
#define CL_INVALID_GL_OBJECT -60
#define CL_INVALID_BUFFER_SIZE -61
#define CL_INVALID_MIP_LEVEL -62
#define CL_INVALID_GLOBAL_WORK_SIZE -63
[/cpp]

研究テーマ

ずっとOpenCLについて勉強しているが、卒論の具体的なテーマについてはまだ決まっていない。
ただ漠然と興味を持ったOpenCLだけど、もう一度OpenCLはなにができるかについて考えた。
OpenCLはデバイス間の互換性を保つことが最大の役割。
 この言葉は非常に曖昧。デバイス間と一言で言っても、CPUの中のIntelとAMDのことを言っているのか、それともCPUとGPUのことを言っているのかによって大きく目指すところが違ってくる。
 もし、同じプロセッサー間のメーカー間の互換性を保つことが役割ならば、各メーカーごとのデバイスで同じプログラムを動かしてみて、性能評価するところからしなければならない。NVIDIAのCUDAとAMDのATI Streamを使った場合とOpenCLを使った場合の比較。そして差があったらなぜそれほどの差が出たかを調べ、その差を埋めるための研究をすればいい。
 もし、異なるプロセッサー間の互換性を保つことが役割ならば、、まず各プロセッサーのMAXの能力指数を図るところから始め、その差を埋めることが必要になる。CPUのシングルコア(単純な逐次での比較)とマルチコア(OpenMP等との比較)、そしてGPU(CPU)をそれぞれのデバイスの持ってる能力をOpenCLで引き出す研究をまずしなければならない。そして次にそれらが複合されたヘテロジニアスな環境下でそのプログラムがその環境のデバイスを一番見合った適材適所で割り振れるようなプログラム開発の研究をするべきだろう。そしてそれと同時に誰もが簡単にソースを使いまわせる(ワークアイテムの数を簡単に変えられる等の変更も含め)ことも必要になってくるだろう。

マンデルブロ集合

この記事はOpenCL入門―GPU&マルチコアCPU並列プログラミング for MacOS Windows Linuxを参考に書いている。
マンデルブロ集合の計算結果に応じて色分けされた画像を、ビットマップ形式のファイルとして生成するプログラム
マンデルブロ集合とは、複素平面上の集合が作り出すフラクタルである。(Wikipedia参照)
$Thanksgiving days to hang out(←旧ときどき日記)-マンデルブロ
↑マンデルブロ集合をxy平面に表したもの
どのような集合かというと
Thanksgiving days to hang out(←旧ときどき日記)-マンデルブロ平面
で定義される複素数列 {zn}n∈N が n → ∞ の極限で無限大に発散しないという条件を満たす複素数 c 全体が作る集合がマンデルブロ集合である。ただこれではただの数列なので、これを平面に表すために、
zn を点 (xn, yn) に、c を点 (a, b) にそれぞれ置き代えて、
Thanksgiving days to hang out(←旧ときどき日記)-マンデルブロ漸化式
とすればいい。
今回はこのマンデルブロ集合を計算し、その書く要素計算結果ごとに色分けし、最後に集合の画像を出力するというプログラムを作成する。
このプログラムを構成するクラスは
$Thanksgiving days to hang out(←旧ときどき日記)
となっている。
プログラムの流れ
1.Mainが
 -Mandelbrot
-VdcMapper
-ClHelper  を作成
2.VdcMapper, ClHelperによって取得した材料をMandelbrotがセットする
3.メインが計算命令
4.Mandelbrotがカーネル作成、メモリオブジェクト作成、カーネル引数の設定、実行リクエスト
5.Calc.cl発動(計算)
6.メインが計算結果を取ってくる
7.画像出力のためにColortableで色をつける
8.Bitmapに渡して、画像出力
そして今回の並列処理について説明する。マンデルブロ集合を求める計算をOpenCLデバイスにしてもらうことになるが、その際に考えなければいけないことが3点ある。
1.カーネル関数
2.インデックス空間の次元
3.ワークアイテムの数
OpenCLデバイスは.clファイルを処理するが、カーネル関数にどのような処理をさせるか、インデックス空間をどのようにとるか、ワークアイテムをどのようにPEに割り振るかを考えなければいけない。

OpenCLの簡単なプログラム

このコードはOpenCL入門―GPU&マルチコアCPU並列プログラミング for MacOS Windows LinuxのChapter 3を参考に、作成した.

[cpp]
{

#include <stdio.h>
#include <time.h>
#include <CL/cl.h>

static void printPlatformInfo(const cl_platform_id platform_id);

/*—————————————————————————
*
*/
int main(int argc, char * const argv[])
{
  //時間計測
  clock_t t1, t2;

  t1= clock();

// プラットフォームIDを取得する
cl_platform_id platforms[10];
cl_uint num_platforms;
cl_int status;

status = clGetPlatformIDs(sizeof(platforms) / sizeof(*platforms),
platforms,
&num_platforms);
if (status != CL_SUCCESS) {
fprintf(stderr, "clGetPlatformIds failed with status %dn", status);
return 1;
}

printf("Number of platform(s) : %dn", num_platforms);
for (int i = 0; i < (int)num_platforms; i++) {
// プラットフォームIDについての情報を表示する
printPlatformInfo(platforms[i]);
}

t2 = clock();
printf("time = %fn", (double)(t2 – t1) / CLOCKS_PER_SEC);

return 0;
}

/*—————————————————————————
* 引数で与えられたプラットフォームの情報を表示する
* platfomrm_id: 情報を表示するプラットフォームのID
*/
static void
printPlatformInfo(const cl_platform_id platform_id)
{
char buffer[1024];
size_t actual_size;
cl_int status;

// プロファイル
status = clGetPlatformInfo(platform_id, CL_PLATFORM_PROFILE,
sizeof(buffer) – 1, buffer, &actual_size);
printf("Platform profile : ");
if (status == CL_SUCCESS) {
buffer[actual_size] = ‘\0’;
printf("%sn", buffer);
} else {
printf("Error: clGetPlatformInfo failed with status %dn", status);
}

// バージョン
status = clGetPlatformInfo(platform_id, CL_PLATFORM_VERSION,
sizeof(buffer) – 1, buffer, &actual_size);

printf("Platform version : ");

if (status == CL_SUCCESS) {
buffer[actual_size] = ‘\0’;
printf("%sn", buffer);
} else {
printf("Error: clGetPlatformInfo failed with status %dn", status);
}

// 名前
status = clGetPlatformInfo(platform_id, CL_PLATFORM_NAME,
sizeof(buffer) – 1, buffer, &actual_size);

printf("Platform name : ");

if (status == CL_SUCCESS) {
buffer[actual_size] = ‘\0’;
printf("%sn", buffer);
} else {
printf("Error: clGetPlatformInfo failed with status %dn", status);
}

// ベンダー
status = clGetPlatformInfo(platform_id, CL_PLATFORM_VENDOR,
sizeof(buffer) – 1, buffer, &actual_size);

printf("Platform vendor : ");

if (status == CL_SUCCESS) {
buffer[actual_size] = ‘\0’;
printf("%sn", buffer);
} else {
printf("Error: clGetPlatformInfo failed with status %dn", status);
}

// 機能拡張
status = clGetPlatformInfo(platform_id, CL_PLATFORM_EXTENSIONS,
sizeof(buffer) – 1, buffer, &actual_size);

printf("Platform extensions: ");

if (status == CL_SUCCESS) {
buffer[actual_size] = ‘\0’;
printf("%sn", buffer);
} else {
printf("Error: clGetPlatformInfo failed with status %dn", status);
}
}
[/cpp]

このプログラム自体はOpenCLデバイスで計算はしていない。OpenCL APIをつかった単なるC++のプログラム。OpenCLデバイスで計算させるためには、OpenCLにデータを飛ばさなければならないため一気に記述する量が多くになる。
それが以下のような一般的なOpenCLプログラムの流れである。
1.コンテキストの作成(clCreateContext)
2.コンテキストに含まれるデバイス取得(clGetContextInfo)
3.コマンドキューの作成(clCreateCommandQueue)
4.プログラムオブジェクトの作成(clCreateProgramWithSource)
5.カーネルプログラムのビルド(clBuildProgram)
6.カーネルオブジェクトの作成(clCreateKernel)
7.メモリオブジェクトの作成(clCreateBuffer)
8.カーネル引数の設定(clSetKernelArg)、実行(clEnqueueTask)
9.メモリバッファから結果取得(clEnqueueReadBuffer)、表示
後ろに括弧で書いておるのがAPIである。このような様々なAPIを利用し、OpenCLデバイスデータを飛ばし計算させデータを取ってくる。僕自身のイメージとして基本的にOpenCLデバイスは本当に計算しかできない。だから、手取り足取りメモリを確保することからカーネルオブジェクトの作成、計算の結果の取得まですべてホストプログラム(CPU)がやれなければならない。
また、OpenCL独特のオンラインコンパイルについて記述する。その前にオフラインコンパイラについての説明から。
オフラインコンパイル方式では,カーネルプログラムをOpenCLコンパイラによって予めコンパイルしておき,ホストプログラム中でOpenCL APIを用いて読み込む方式である.プログラム中でコンパイルを行う必要がなく,カーネルプログラムの起動で生じるラグが少ないことが利点である.しかし,移植性を高めたい場合には,様々なアーキテクチャに対応させたカーネルプログラムにしなければならないため,必然的にプログラムサイズが大きくなる.多くのデバイスのメモリ容量は少ないことが多いので,この点でオフライン方式は不利となる.また,現状ではオンラインコンパイルのみをサポートし,オフラインコンパイルをサポートしていない実装がいくつかある.(http://www.is.doshisha.ac.jp/report/2010/9/17/2010030001/index.htmlより引用)
つまり、これが普通のコンパイル。ホストプログラムもカーネルプログラムも全部コンパイルして実行ファイルを作ってしまう。そしたら楽なんだけど、移植性は低くなっちゃうよねって話。
それとは反対のオンラインコンパイル
オフラインコンパイル方式とは反対に,プログラム実行時にカーネルプログラムをコンパイルする方式がオンラインコンパイル方式である.デバイスのアーキテクチャに依存することなく,環境に応じて適応的にコンパイルできる点がオンライン方式の利点である.しかし,リアルタイム性が要求される組み込み用途,ソースコードを非公開にしたい場合などにはコンパイル分のオーバーヘッドが付くのでこの方式は適していない.現存のすべての実装で,この方式をサポートしている.(http://www.is.doshisha.ac.jp/report/2010/9/17/2010030001/index.htmlより引用)
つまり、これがOpenCL独特のコンパイル方式。予めコンパイルしておくのはホストプログラムだけ。ホストプログラムだけから作った実行ファイルを実行時に、その実行環境にあった並列処理(?)でカーネルプログラムを処理してくれるというもの。計算量が莫大になればなるほどおそらく逐次より早く動くものと思われる。

OpenCLインストール

さてさて前回の更新から1ヶ月近くたってしまったんですが、いろいろ忙しかったんす。申し訳。
引き続きOpenCL勉強しています。自分のためにも、ここに記録します。
OpenCLインストール方法ってか使うまで準備
実行環境
Intel Core i7 CPU 920 @2.67GHz 2.66GHz
GeForce 9800 GT
実装メモリ(RAM) 6.00GB
Windows 7 Professional 64bit
Microsoft Visual Studio 2010 Professional
OpenCLはMacは最初からサポートされているらしい
ぼくはWindowsなのでいろいろインストールしなければならないらしい
①OpenCL SDKを入れる(Windowsの場合)
http://software.intel.com/en-us/articles/vcsource-tools-opencl-sdk/ に行って右上の青いところからダウンロード(別に登録しなくてもいける)
そんでインストール
②NVIDIAのOpenCLドライバを入れる(NVIDIAの場合)
http://developer.nvidia.com/cuda-downloads に行って自分の環境にあったものをNVIDIAドライバ、CUDA Toolkit、GPU Computing SDKの順にダウンロードし、インストール
基本的にインストールは次へ連打でおk。でもGPU Computing SDKの保存場所は覚えておくように。のちのち使う。
③Visual Studioへの環境設定
 ぼくは学校でもらえるMicrosoft Visual Studio 2010 Professionalを使ったが、無料で入手できるVisual C++ 2010 Expressでも出来るらしい
 ここからが少しややこしいんだけど、、、
これはプロジェクトを作るたびに毎回設定しなければならない。まずVisual Studio起動して、「ファイル」→「新規作成」→「プロジェクト」で新しいプロジェクトを作る。このときにインストールされたテンプレートでVirtual C++の中でOpenCLではなく普通のWin32コンソールアプリケーションを選ぶ。名前は何でもいい。次へを押し、アプリケーションの設定で追加のオプションのカラのプロジェクトにチェック。完了。
 次にソリューションエクスプローラのソースファイルのフォルダを右クリックし、「追加」→「新しい項目」を開く。そしてC++ファイルを追加する。
ここから具体的な設定に入る
1.次にソリューションエクスプローラにあるプロジェクト名を右クリックし「プロパティ」へ。
まずしなければならないのは、構成を「アクティブ(Debug)」から「すべての構成」
に変更する。そして「構成プロパティ」→「C/C++」→「全般」を開き、「追加のインクルードディレクトリ」に次のパスを登録する。
Intelの場合
“C:Program Files (x86)IntelOpenCL SDK2.0include”
また、環境変数の相対パスを使ってもできる。その場合は、
$(INTELOCLSDKROOT)include
と指定。
NVIDIAの場合
“C:ProgramDataNVIDIA CorporationNVIDIA GPU Computing SDK 4.2OpenCLcommoninc”的なパスを指定。エクスプローラで確認してみると良い。
また、環境変数の相対パスを使ってもできる。その場合は、
$(CUDA_INC_PATH)
と指定。
IntelとNVIDIAの両方を設定したい場合は「;」で区切ってください。
2.プロパティを開いたそのまま、「構成プロパティ」→「リンカー」→「全般」を開き、「追加のライブラリディレクトリ」に次のパスを登録する。
Intelの場合
“C:Program Files (x86)IntelOpenCL SDK2.0libx86”
環境変数の相対パスだと
$(INTELOCLSDKROOT)libx86
NVIDIAの場合
“C:ProgramDataNVIDIA CorporationNVIDIA GPU Computing SDK 4.2OpenCLcommonlibWin32”
環境変数の相対パスだと
$(CUDA_INC_PATH)libWin32
ここでは32bit版か64bit版かでパスが変わってきます。エクスプローラで確認してみると良い。
3.プロパティを開いたそのまま、「構成プロパティ」→「リンカー」→「入力」を開き、「追加の依存ファイル」に次のライブラリ名を登録する。
IntelもNVIDIAも共通で
「OpenCL.lib」
大文字小文字を間違えないように。また、すでにライブラリが登録されている場合は、「;」をつけてから書き加える。
以上でOpenCLの設定は終わりです。
基本的にコンパイルはVSで行うことになると思うが、コマンドプロンプトでやる場合には
g++ main.cpp -lOpenCLl
でコンパイルすることができる。

今日からOpenCL本格的に勉強すっから

まぁ簡単な話、卒論っすよ。 
OpenCLとはなにか?
●CPU, GPU, DSP等が混在するプラットホームで並列処理プログラムを書くためのフレームワーク
●ヘテロジニアス(異種混交)な並列計算機環境に適した並列プログラミングのためのフレームワーク
高クロック化からマルチコア化という背景があって提唱されはじめた。
まぁ簡単に言うと、OpenCLを利用する事により、様々な計算資源に共通のインターフェースでアクセス・制御が可能となる。
もっとわかりやすく言うと、CPUとかGPUっていうコンピュータの頭脳があるんだけど、その頭脳によっても得手不得手があるから、計算が得意なGPUには計算だけさせて、タスク処理(?)が得意なCPUにはタスク処理だけさせようって話。GPU使わなくてもCPUだけの並列化もできるんだけど。
これはGPGPUのCUDAに非常に近い考え方なんだけど、それをNVIDIA以外のやつにも対応させようって話。
主にこれが概要。
メリット
エンドユーザー側
●単純にパソコンが高速になる
●演算デバイスの違いを気にすることなく利用できる
●プロセッサーを自由に選択できる
エンジニア側
●言語がCをベースにしており習得が容易な点(ソフトウェア)
●ソフトウェアレイヤーにおける互換性を意識せずにすむ(ハードウェア)
こんな感じ。意外とメリットが高速化以外に見つからない。
論文の内容についてはまだ模索中。