2016年11月13日 星期日

用 Eclipse 寫 OpenCL 的 Hello World 程式

安裝好「OpenCL 程式框架」後,就可以開始寫第一個 OpenCL 的程式了。一些相關發文列在下方,請讀者自行參閱:

一、安裝 OpenCL 「標頭檔」

欲開發 OpenCL 需先安裝開發用的「標頭檔 (header file)」,在 Fedora 安裝很簡單,只要下這個命令即可,
[root@Core-i7 ~]# dnf install opencl-headers
接著,就可以開始測試第一個 OpenCL 的 Hello World 範例程式。

二、下載並修改 OpenCL 範例程式

Apple 的官網下載 OpenCL 範例,用其中的『hello.c』程式取代前文〝在 Linux 中,用 Eclipse 寫第一個程式 HelloWorld〞的 C 程式。這個程式並不能立即編譯,要先做過以下修改才行。

1. 修改載入的標頭檔之位置、名稱

原先的範例是只供 Apple 電腦用的,將這列
 . . . . .
#include <OpenCL/opencl.h>
 . . . . .
改成
 . . . . .
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
 . . . . .
才可在 Fedora 系統中編譯。

2. 在取得 OpenCL 裝置前,先取得 OpenCL 平台資訊

原範例程式,直接呼叫 clGetDeviceIDs( ),以獲得可用的 OpenCL 裝置。
 . . . . .
// Connect to a compute device
//
int gpu = 1;
err = clGetDeviceIDs(NULL, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &device_id, NULL);
if (err != CL_SUCCESS)
 . . . . .
上例中 NULL 這個位置應該是填入 OpenCL 平台的識別名 (ID),若填入 NULL 則依 OpenCL 程式框架的實作而定。在非 Mac OS 系統通常要指定 OpenCL 平台才可以,將上述的程式碼改成
 . . . . .
// Get one ID of platforms
cl_platform_id PlatformID;
err = clGetPlatformIDs(1, &PlatformID, NULL);
if (err != CL_SUCCESS)
{
    printf("Error: Failed to get one ID of platform! (%d)\n", err);
    return EXIT_FAILURE;
}

// Connect to a compute device
//
err = clGetDeviceIDs(PlatformID, CL_DEVICE_TYPE_ALL, 1, &device_id, NULL);
if (err != CL_SUCCESS)
 . . . . .
上例中是只取用第一個測試得到的 OpenCL 平台,在從中取用第一個獲得的 OpenCL 裝置,不論其型態。

:OpenCL 裝置可為:CPU, GPU, ACCELERATOR。

3. 自動分割 OpenCL 的『整體工作項目』至適當的『工作群組』

OpenCL 執行時,需正確分割『整體工作項目 (global work-item)』至『工作群組 (work-group)』,以正確處理運算資料。
 . . . . .
err = clEnqueueNDRangeKernel(commands, kernel, 1, NULL, &global, &local, 0, NULL, NULL);
 . . . . .
原範例中為 &local,在某些測試的平台上並不能正確執行,會出現以下這個錯誤訊息。
Error: Failed to execute kernel! (-54)
這是因為它分割錯誤所致,將這列改成
 . . . . .
err = clEnqueueNDRangeKernel(commands, kernel, 1, NULL, &global, NULL, 0, NULL, NULL);
 . . . . .
分割的動作交由 OpenCL 程式框架自動處理。

:由 OpenCL 程式框架自動分割,因其結果可能並不是最佳化,而影響 OpenCL 效能,不過,就以能執行優先的考量,這個改法相對是比較簡單。

三、在 Eclipse 設定 OpenCL 專案的編譯設定

在 Eclipse 的 OpenCL 專案中,還需要一點設定,才可以正確編譯 OpenCL 程式。從 Eclipse 的「選單」→「專案(P)」點選「內容(P)」,以設定專案的內容。
  • 當跳出專案設定視窗後,從左欄的「C/C++ Build」點選「Settings」,接著再設定右欄 Settings。在右欄中的「Configuration:」選 "[All Configurations]",使「除錯版」與「釋出版」有相同設定。
  • 設定編譯的參數要從「Tool Settings」分頁→「GCC C Linker」點選「Libraries」。在右方的「Libraries (-l)」按『』加上 OpenCL 這個參數 。

四、執行 OpenCL 專案

做完以上操作後,就可以正確編譯 OpenCL 專案。執行以上 OpenCL 專案的結果如下:
Computed '1024/1024' correct values!
將 DATA_SIZE 改成較大的數字 102400,結果變成
Computed '102400/102400' correct values!

已測試版本、平台:

  • Fedora: 22, 23, 24
  • OpenCL Platform:
    • NVIDIA GPU : GeForce GTX 950M
    • Intel GPU : Intel(R) HD Graphics
    • Intel CPU : Intel(R) Core(TM) i7-4720HQ

參考資料:

沒有留言:

張貼留言

感謝你耐心看完本文,歡迎留下任何指正、建議,筆者會儘快回應。(English is also welcome.)