最終更新: 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; }