OpenCLを用いた"Hello"の表示
こんにちは、OpenCLの勉強をしている学生です。
OpenCL入門という本を読み、Helloを表示させるサンプルプログラムを実行させたのですがMacbookPro上のMacOSXでは動くのに対し、自作マシンのWindows7上ではコンパイルは通るがうまく動作しないという問題でて、コードをいろいろ書き換えたのですができず悩んでいます。
大まかな環境はそれぞれ以下の通りです。
MacBookPro
OS:snow leopard
型番:MacBook Pro 2260/13.3 MB990J/A
Xcodeにてビルド
自作マシン
OS:Windows7 Enterprise(64bit)
CPU:Core2Quad Q9550
GPU:Geforce GTX260
memory:8G
visual studio2008 Express Editionにてビルド
1)元のコードは以下の通りです
#include"hello.h"
#define MEM_SIZE (128)
#define MAX_SOURCE_SIZE (0x100000)
int main(){
cl_device_id device_id=NULL;
cl_context context=NULL;
cl_command_queue command_queue=NULL;
cl_mem memobj=NULL;
cl_program program=NULL;
cl_kernel kernel=NULL;
cl_platform_id platform_id=NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
cl_int ret;
char string[MEM_SIZE];
FILE *fp;
char fileName[]="./hello.cl";
char *source_str;
size_t source_size;
//カーネルを含むソースコードをロード
fp=fopen(fileName,"r");
if(!fp){
fprintf(stderr,"Failed to load kernel.\n");
exit(1);
}
source_str=(char*)malloc(MAX_SOURCE_SIZE);
source_size=fread(source_str,1,MAX_SOURCE_SIZE,fp);
fclose(fp);
//プラットフォーム、デバイス情報の取得
ret= clGetPlatformIDs(1,&platform_id,&ret_num_platforms);
ret = clGetDeviceIDs(platform_id,CL_DEVICE_TYPE_DEFAULT,1,&device_id,&ret_num_devices);
//OpenCLコンテキストの作成
context=clCreateContext(NULL,1,&device_id,NULL,NULL,&ret);
//コマンドキューの作成
command_queue=clCreateCommandQueue(context,device_id,0,&ret);
//メモリバッファの作成
memobj= clCreateBuffer(context,CL_MEM_READ_WRITE,MEM_SIZE * sizeof(char),NULL,&ret);
//読み込んだソースからカーネルプログラムを作成
program=clCreateProgramWithSource(context,1,(const char **)&source_str,(const size_t *)&source_size,&ret);
//カーネルプログラムをビルド
ret = clBuildProgram(program,1,&device_id,NULL,NULL,NULL);
//OoenCLカーネルの作成
kernel = clCreateKernel(program,"hello",&ret);
//OpenlCL カーネル引数の設定
ret = clSetKernelArg(kernel,0,sizeof(cl_mem),(void *)&memobj);
//OpenCLカーネルを実行
ret = clEnqueueTask(command_queue,kernel,0,NULL,NULL);
//メモリバッファから結果を取得
ret = clEnqueueReadBuffer(command_queue,memobj,CL_TRUE,0,MEM_SIZE * sizeof(char),string,0,NULL,NULL);
//結果の表示
puts(string);
//終了処理
ret=clFlush(command_queue);
ret=clFinish(command_queue);
ret=clReleaseKernel(kernel);
ret=clReleaseProgram(program);
ret=clReleaseMemObject(memobj);
ret=clReleaseCommandQueue(command_queue);
ret=clReleaseContext(context);
free(source_str);
return 0;
}
結果は
MacbookPro:Hello
Windows7:fpに値がなぜか代入されず(fopenがうまく動いてない?)途中(fread)でアクセス違反
2)また、fopen等がだめならと思い、その部分(カーネルを含むソースコードをロード)のコードを以下のように書き直しビルドしました。
fstream ifs(fileName,ios::in);
if(ifs.fail()){
fprintf(stderr,"Failed to load kernel");
exit(1);
}
source_str=(char*)malloc(MAX_SOURCE_SIZE);
std::string strbuf,strsrc;
while(!ifs.eof())//ファイルの最後まで
{
ifs.getline(source_str,MAX_SOURCE_SIZE);
strsrc+=source_str;
}
source_str=(char*)strsrc.c_str();
source_size=(int)strsrc.length();
結果は
MacBookPro:Hello
Windows7:フフフフフフ‥‥
こちらはデバックするとsource_strなどにはうまく文字列が入っているのですが、kernelに値がはいっていない(0x00000)のです。どうしてそんなことが起きるのか、どう直せばいいかさっぱりです。
できれば1)を少しだけ改良して直したいと思っているのですが、2)の部分も何が原因か分かると嬉しいです。
どうか知恵をお貸しください。よろしくお願いします。