最終更新:
mikk_ni3_92 2010年06月05日(土) 14:42:54履歴
現在地 >> メニュー >> OpenCL >> OpenCL編02 >> OpenCL編02::まとめ1
__kernel void gpuMain(__global int *Ary)
{
unsigned int id = get_global_id(0);//配列の通し番号でID取得
Ary[id] += 1000;
}
#include <oclUtils.h>//OpenCL用ユーティティヘッダ
#include <fstream>
#include <iostream>
//OpenCL用グローバル変数
cl_context cxGPUContext;//OpenCLコンテキスト用
cl_kernel myclKernel; //OpenCLのカーネル用
cl_command_queue commandQueue;//コマンドキュー
const int aryNUM = 100;
int sampleData[aryNUM];
//------- メイン --------//
int main(int argc, const char** argv)
{
//初期設定
for(int loop = 0; loop < aryNUM; ++loop)
{
sampleData[loop] = loop + 1;
std::cout << sampleData[loop] << "\n";
}
std::cout << "Start!\n";
cl_int ciErrNum = CL_SUCCESS; //エラーチェック用
//--- プラットフォームIDの取得 ---//
cl_platform_id cpPlatform = NULL;//プラットフォームID
ciErrNum = oclGetPlatformID(&cpPlatform);
if (ciErrNum != CL_SUCCESS)
{
std::cerr << "Can't Get PlatformID\n";
shrEXIT(argc,argv);
}
//--- デバイスの取得 ---//
cl_uint ciDeviceCount = 0; //デバイス数
cl_device_id *cdDevices = NULL;//デバイスID
//デバイス数取得 → デバイスID取得
ciErrNum = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 0, NULL, &ciDeviceCount);
cdDevices = new cl_device_id[ciDeviceCount];
ciErrNum = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, ciDeviceCount, cdDevices, NULL);
if (ciErrNum != CL_SUCCESS)
{
std::cerr << "Error @ Getting device Infomation\n";
shrEXIT(argc,argv);
}
//コンテキストの作成
cxGPUContext = clCreateContext(0, ciDeviceCount, cdDevices, NULL, NULL, &ciErrNum);
if (ciErrNum != CL_SUCCESS)
{
std::cerr << "Can't Create OpenCL Context\n";
shrEXIT(argc, argv);
}
//コマンドキューの作成
commandQueue = clCreateCommandQueue(cxGPUContext, (*cdDevices), 0, &ciErrNum);
if (ciErrNum != CL_SUCCESS)
{
std::cerr << " Error in clCreateCommandQueue call !!!\n";
shrEXIT(argc, argv);
}
//GPUのソースコードを読み込む
std::ifstream myclSource("gpuMain.cl");
std::istreambuf_iterator<char> vdataBegin(myclSource);
std::istreambuf_iterator<char> vdataEnd;
std::string myclStr(vdataBegin,vdataEnd);
const char *bfile = myclStr.c_str();
const size_t program_length = myclStr.size();
//プログラムを作成する
cl_program cpProgram = clCreateProgramWithSource(cxGPUContext, 1, &bfile, &program_length, &ciErrNum);
if (ciErrNum != CL_SUCCESS)
{
std::cerr << "Error: Failed to create program\n";
shrEXIT(argc, argv);
}
//プログラムのビルド
ciErrNum = clBuildProgram(cpProgram, 0, NULL, NULL, NULL, NULL);
if (ciErrNum != CL_SUCCESS)
{
shrLogEx(LOGBOTH | ERRORMSG, ciErrNum, STDERROR);//ログの出力
shrEXIT(argc, argv);
}
//カーネルの作成
myclKernel = clCreateKernel(cpProgram, "gpuMain", &ciErrNum);
if (ciErrNum != CL_SUCCESS)
{
shrLog("Error: Failed to create kernel\n");//ログの出力
shrEXIT(argc, argv);
}
//---- ここからGPUの処理 ----//
//デバイス上にメモリ確保
cl_mem dviceAry = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
sizeof(sampleData), &sampleData, NULL);
/*cl_mem dviceAry = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
sizeof(sampleData), &sampleData, NULL);*/
sampleData[99] = 900;//GPU側には反映されない
//データをコピー
clEnqueueWriteBuffer(commandQueue,dviceAry,CL_TRUE,0,sizeof(sampleData),sampleData,0,NULL,NULL);
//カーネルに引数を設定する
clSetKernelArg(myclKernel,0,sizeof(cl_mem), (void *) &dviceAry);
//実行
//CUDAとOpenCLの用語の対応
//Thread == work-item
//block == workgroup
size_t WorkSize[1] = {aryNUM};//ワークサイズ
clEnqueueNDRangeKernel(commandQueue, myclKernel, 1, NULL, WorkSize, NULL,0, NULL, NULL);
//データを取り出し
clEnqueueReadBuffer(commandQueue, dviceAry, CL_TRUE, 0,sizeof(sampleData), &sampleData, 0, NULL, NULL);
//使い終わったらコンテキストなどの各種破棄
clReleaseContext(cxGPUContext);
clReleaseKernel(myclKernel);
clReleaseProgram(cpProgram);
clReleaseCommandQueue(commandQueue);
clReleaseMemObject(dviceAry);
delete [] cdDevices;
std::cout << "------------- after --------------------------\n";
for(int loop = 0; loop < aryNUM; ++loop)
{
std::cout << sampleData[loop] << "\n";
}
shrEXIT(argc, argv);//ログ等を出力して終了へ
return 0;
}

